UNPKG

@ckeditor/ckeditor5-integrations-common

Version:

This package implements common utility modules for integration projects.

880 lines (838 loc) 29.6 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.CKEDITOR_INTEGRATIONS_COMMON = {})); })(this, (function (exports) { 'use strict'; /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function createDefer() { const deferred = { resolve: null, promise: null }; deferred.promise = new Promise((resolve) => { deferred.resolve = resolve; }); return deferred; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function waitFor(callback, { timeOutAfter = 500, retryAfter = 100 } = {}) { return new Promise((resolve, reject) => { const startTime = Date.now(); let lastError = null; const timeoutTimerId = setTimeout(() => { reject(lastError ?? new Error("Timeout")); }, timeOutAfter); const tick = async () => { try { const result = await callback(); clearTimeout(timeoutTimerId); resolve(result); } catch (err) { lastError = err; if (Date.now() - startTime > timeOutAfter) { reject(err); } else { setTimeout(tick, retryAfter); } } }; tick(); }); } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ const INJECTED_SCRIPTS = /* @__PURE__ */ new Map(); function injectScript(src, { attributes } = {}) { if (INJECTED_SCRIPTS.has(src)) { return INJECTED_SCRIPTS.get(src); } const maybePrevScript = document.querySelector(`script[src="${src}"]`); if (maybePrevScript) { console.warn(`Script with "${src}" src is already present in DOM!`); maybePrevScript.remove(); } const promise = new Promise((resolve, reject) => { const script = document.createElement("script"); script.onerror = reject; script.onload = () => { resolve(); }; for (const [key, value] of Object.entries(attributes || {})) { script.setAttribute(key, value); } script.setAttribute("data-injected-by", "ckeditor-integration"); script.type = "text/javascript"; script.async = true; script.src = src; document.head.appendChild(script); const observer = new MutationObserver((mutations) => { const removedNodes = mutations.flatMap((mutation) => Array.from(mutation.removedNodes)); if (removedNodes.includes(script)) { INJECTED_SCRIPTS.delete(src); observer.disconnect(); } }); observer.observe(document.head, { childList: true, subtree: true }); }); INJECTED_SCRIPTS.set(src, promise); return promise; } async function injectScriptsInParallel(sources, props) { await Promise.all( sources.map((src) => injectScript(src, props)) ); } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ const INJECTED_STYLESHEETS = /* @__PURE__ */ new Map(); function injectStylesheet({ href, placementInHead = "start", attributes = {} }) { if (INJECTED_STYLESHEETS.has(href)) { return INJECTED_STYLESHEETS.get(href); } const maybePrevStylesheet = document.querySelector(`link[href="${href}"][rel="stylesheet"]`); if (maybePrevStylesheet) { console.warn(`Stylesheet with "${href}" href is already present in DOM!`); maybePrevStylesheet.remove(); } const appendLinkTagToHead = (link) => { const previouslyInjectedLinks = Array.from( document.head.querySelectorAll('link[data-injected-by="ckeditor-integration"]') ); switch (placementInHead) { case "start": if (previouslyInjectedLinks.length) { previouslyInjectedLinks.slice(-1)[0].after(link); } else { document.head.insertBefore(link, document.head.firstChild); } break; case "end": document.head.appendChild(link); break; } }; const promise = new Promise((resolve, reject) => { const link = document.createElement("link"); for (const [key, value] of Object.entries(attributes || {})) { link.setAttribute(key, value); } link.setAttribute("data-injected-by", "ckeditor-integration"); link.rel = "stylesheet"; link.href = href; link.onerror = reject; link.onload = () => { resolve(); }; appendLinkTagToHead(link); const observer = new MutationObserver((mutations) => { const removedNodes = mutations.flatMap((mutation) => Array.from(mutation.removedNodes)); if (removedNodes.includes(link)) { INJECTED_STYLESHEETS.delete(href); observer.disconnect(); } }); observer.observe(document.head, { childList: true, subtree: true }); }); INJECTED_STYLESHEETS.set(href, promise); return promise; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function isSSR() { return typeof window === "undefined"; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function once(fn) { let lastResult = null; return (...args) => { if (!lastResult) { lastResult = { current: fn(...args) }; } return lastResult.current; }; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function overwriteArray(source, destination) { destination.length = 0; destination.push(...source); return destination; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ 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-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function preloadResource(url, { attributes } = {}) { if (document.head.querySelector(`link[href="${url}"][rel="preload"]`)) { return; } const link = document.createElement("link"); for (const [key, value] of Object.entries(attributes || {})) { link.setAttribute(key, value); } link.setAttribute("data-injected-by", "ckeditor-integration"); link.rel = "preload"; link.as = detectTypeOfResource(url); link.href = url; document.head.insertBefore(link, document.head.firstChild); } function detectTypeOfResource(url) { switch (true) { case /\.css$/.test(url): return "style"; case /\.js$/.test(url): return "script"; default: return "fetch"; } } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function 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-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ const HEX_NUMBERS = new Array(256).fill("").map((_, index) => ("0" + index.toString(16)).slice(-2)); function uid() { const [r1, r2, r3, r4] = crypto.getRandomValues(new Uint32Array(4)); 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-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function uniq(source) { return Array.from(new Set(source)); } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ async function waitForWindowEntry(entryNames, config) { const tryPickBundle = () => entryNames.map((name) => window[name]).filter(Boolean)[0]; return waitFor( () => { const result = tryPickBundle(); if (!result) { throw new Error(`Window entry "${entryNames.join(",")}" not found.`); } return result; }, config ); } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function filterObjectValues(obj, filter) { const filteredEntries = Object.entries(obj).filter(([key, value]) => filter(value, key)); return Object.fromEntries(filteredEntries); } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function filterBlankObjectValues(obj) { return filterObjectValues( obj, (value) => value !== null && value !== void 0 ); } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function mapObjectValues(obj, mapper) { const mappedEntries = Object.entries(obj).map(([key, value]) => [key, mapper(value, key)]); return Object.fromEntries(mappedEntries); } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function without(itemsToRemove, items) { return items.filter((item) => !itemsToRemove.includes(item)); } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function appendExtraPluginsToEditorConfig(config, plugins) { const extraPlugins = config.extraPlugins || []; return { ...config, extraPlugins: [ ...extraPlugins, ...plugins.filter((item) => !extraPlugins.includes(item)) ] }; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function isSemanticVersion(version) { return !!version && /^\d+\.\d+\.\d+/.test(version); } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function isCKCdnTestingVersion(version) { if (!version) { return false; } return ["nightly", "alpha", "internal", "nightly-", "staging"].some((testVersion) => version.includes(testVersion)); } function isCKCdnVersion(version) { return isSemanticVersion(version) || isCKCdnTestingVersion(version); } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function destructureSemanticVersion(version) { if (!isSemanticVersion(version)) { throw new Error(`Invalid semantic version: ${version || "<blank>"}.`); } const [major, minor, patch] = version.split("."); return { major: Number.parseInt(major, 10), minor: Number.parseInt(minor, 10), patch: Number.parseInt(patch, 10) }; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function getLicenseVersionFromEditorVersion(version) { if (isCKCdnTestingVersion(version)) { return 3; } const { major } = destructureSemanticVersion(version); switch (true) { case major >= 44: return 3; case major >= 38: return 2; default: return 1; } } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function getCKBaseBundleInstallationInfo() { const { CKEDITOR_VERSION, CKEDITOR } = window; if (!isCKCdnVersion(CKEDITOR_VERSION)) { return null; } return { source: CKEDITOR ? "cdn" : "npm", version: CKEDITOR_VERSION }; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function getSupportedLicenseVersionInstallationInfo() { const installationInfo = getCKBaseBundleInstallationInfo(); if (!installationInfo) { return null; } return getLicenseVersionFromEditorVersion(installationInfo.version); } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function isCKEditorFreeLicense(licenseKey, licenseVersion) { licenseVersion ||= getSupportedLicenseVersionInstallationInfo() || void 0; switch (licenseVersion) { case 1: case 2: return licenseKey === void 0; case 3: return licenseKey === "GPL"; default: { return false; } } } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function createIntegrationUsageDataPlugin(integrationName, usageData) { return function IntegrationUsageDataPlugin(editor) { if (isCKEditorFreeLicense(editor.config.get("licenseKey"))) { return; } editor.on("collectUsageData", (source, { setUsageData }) => { setUsageData(`integration.${integrationName}`, usageData); }); }; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ const CK_CDN_URL = "https://cdn.ckeditor.com"; function createCKCdnUrl(bundle, file, version) { return `${CK_CDN_URL}/${bundle}/${version}/${file}`; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ const CKBOX_CDN_URL = "https://cdn.ckbox.io"; function createCKBoxCdnUrl(bundle, file, version) { return `${CKBOX_CDN_URL}/${bundle}/${version}/${file}`; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ const CK_DOCS_URL = "https://ckeditor.com/docs/ckeditor5"; function createCKDocsUrl(path, version = "latest") { return `${CK_DOCS_URL}/${version}/${path}`; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function createCKCdnBaseBundlePack({ version, translations, createCustomCdnUrl = createCKCdnUrl }) { const urls = { scripts: [ // Load the main script of the base features. createCustomCdnUrl("ckeditor5", "ckeditor5.umd.js", version), // Load all JavaScript files from the base features. // EN bundle is prebuilt into the main script, so we don't need to load it separately. ...without(["en"], translations || []).map( (translation) => createCustomCdnUrl("ckeditor5", `translations/${translation}.umd.js`, version) ) ], stylesheets: [ createCustomCdnUrl("ckeditor5", "ckeditor5.css", version) ] }; return { // Preload resources specified in the pack, before loading the main script. preload: [ ...urls.stylesheets, ...urls.scripts ], scripts: [ // It's safe to load translations and the main script in parallel. async (attributes) => injectScriptsInParallel(urls.scripts, attributes) ], // Load all stylesheets of the base features. stylesheets: urls.stylesheets, // Pick the exported global variables from the window object. checkPluginLoaded: async () => waitForWindowEntry(["CKEDITOR"]), // Check if the CKEditor base bundle is already loaded and throw an error if it is. beforeInject: () => { const installationInfo = getCKBaseBundleInstallationInfo(); switch (installationInfo?.source) { case "npm": throw new Error( "CKEditor 5 is already loaded from npm. Check the migration guide for more details: " + createCKDocsUrl("updating/migration-to-cdn/vanilla-js.html") ); case "cdn": if (installationInfo.version !== version) { throw new Error( `CKEditor 5 is already loaded from CDN in version ${installationInfo.version}. Remove the old <script> and <link> tags loading CKEditor 5 to allow loading the ${version} version.` ); } break; } } }; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function createCKCdnPremiumBundlePack({ version, translations, createCustomCdnUrl = createCKCdnUrl }) { const urls = { scripts: [ // Load the main script of the premium features. createCustomCdnUrl("ckeditor5-premium-features", "ckeditor5-premium-features.umd.js", version), // Load all JavaScript files from the premium features. // EN bundle is prebuilt into the main script, so we don't need to load it separately. ...without(["en"], translations || []).map( (translation) => createCustomCdnUrl("ckeditor5-premium-features", `translations/${translation}.umd.js`, version) ) ], stylesheets: [ createCustomCdnUrl("ckeditor5-premium-features", "ckeditor5-premium-features.css", version) ] }; return { // Preload resources specified in the pack, before loading the main script. preload: [ ...urls.stylesheets, ...urls.scripts ], scripts: [ // It's safe to load translations and the main script in parallel. async (attributes) => injectScriptsInParallel(urls.scripts, attributes) ], // Load all stylesheets of the premium features. stylesheets: urls.stylesheets, // Pick the exported global variables from the window object. checkPluginLoaded: async () => waitForWindowEntry(["CKEDITOR_PREMIUM_FEATURES"]) }; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ async function loadCKCdnResourcesPack(pack) { let { htmlAttributes = {}, scripts = [], stylesheets = [], preload, beforeInject, checkPluginLoaded } = normalizeCKCdnResourcesPack(pack); beforeInject?.(); if (!preload) { preload = uniq([ ...stylesheets.filter((item) => typeof item === "string"), ...scripts.filter((item) => typeof item === "string") ]); } for (const url of preload) { preloadResource(url, { attributes: htmlAttributes }); } await Promise.all( uniq(stylesheets).map((href) => injectStylesheet({ href, attributes: htmlAttributes, placementInHead: "start" })) ); for (const script of uniq(scripts)) { const injectorProps = { attributes: htmlAttributes }; if (typeof script === "string") { await injectScript(script, injectorProps); } else { await script(injectorProps); } } return checkPluginLoaded?.(); } function normalizeCKCdnResourcesPack(pack) { if (Array.isArray(pack)) { return { scripts: pack.filter( (item) => typeof item === "function" || item.endsWith(".js") ), stylesheets: pack.filter( (item) => item.endsWith(".css") ) }; } if (typeof pack === "function") { return { checkPluginLoaded: pack }; } return pack; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function combineCKCdnBundlesPacks(packs) { const normalizedPacks = mapObjectValues( filterBlankObjectValues(packs), normalizeCKCdnResourcesPack ); const mergedPacks = Object.values(normalizedPacks).reduce( (acc, pack) => { acc.scripts.push(...pack.scripts ?? []); acc.stylesheets.push(...pack.stylesheets ?? []); acc.preload.push(...pack.preload ?? []); return acc; }, { preload: [], scripts: [], stylesheets: [] } ); const checkPluginLoaded = async () => { const exportedGlobalVariables = /* @__PURE__ */ Object.create(null); for (const [name, pack] of Object.entries(normalizedPacks)) { exportedGlobalVariables[name] = await pack?.checkPluginLoaded?.(); } return exportedGlobalVariables; }; const beforeInject = () => { for (const pack of Object.values(normalizedPacks)) { pack.beforeInject?.(); } }; return { ...mergedPacks, beforeInject, checkPluginLoaded }; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function getCKBoxInstallationInfo() { const version = window.CKBox?.version; if (!isSemanticVersion(version)) { return null; } return { source: "cdn", version }; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function createCKBoxBundlePack({ version, theme = "lark", translations, createCustomCdnUrl = createCKBoxCdnUrl }) { return { // Load the main script of the base features. scripts: [ createCustomCdnUrl("ckbox", "ckbox.js", version), // EN bundle is prebuilt into the main script, so we don't need to load it separately. ...without(["en"], translations || []).map( (translation) => createCustomCdnUrl("ckbox", `translations/${translation}.js`, version) ) ], // Load optional theme, if provided. It's not required but recommended because it improves the look and feel. ...theme && { stylesheets: [ createCustomCdnUrl("ckbox", `styles/themes/${theme}.css`, version) ] }, // Pick the exported global variables from the window object. checkPluginLoaded: async () => waitForWindowEntry(["CKBox"]), // Check if the CKBox bundle is already loaded and throw an error if it is. beforeInject: () => { const installationInfo = getCKBoxInstallationInfo(); if (installationInfo && installationInfo.version !== version) { throw new Error( `CKBox is already loaded from CDN in version ${installationInfo.version}. Remove the old <script> and <link> tags loading CKBox to allow loading the ${version} version.` ); } } }; } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function isCKCdnSupportedByEditorVersion(version) { if (isCKCdnTestingVersion(version)) { return true; } const { major } = destructureSemanticVersion(version); const licenseVersion = getLicenseVersionFromEditorVersion(version); switch (licenseVersion) { case 3: return true; default: return major === 43; } } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function combineCdnPluginsPacks(pluginsPacks) { const normalizedPluginsPacks = mapObjectValues(pluginsPacks, (pluginPack, pluginName) => { if (!pluginPack) { return void 0; } const normalizedPluginPack = normalizeCKCdnResourcesPack(pluginPack); return { // Provide default window accessor object if the plugin pack does not define it. checkPluginLoaded: async () => waitForWindowEntry([pluginName]), // Transform the plugin pack to a normalized advanced pack. ...normalizedPluginPack }; }); return combineCKCdnBundlesPacks( normalizedPluginsPacks ); } /** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ function loadCKEditorCloud(config) { const { version, translations, plugins, premium, ckbox, createCustomCdnUrl, injectedHtmlElementsAttributes = { crossorigin: "anonymous" } } = config; validateCKEditorVersion(version); const pack = combineCKCdnBundlesPacks({ CKEditor: createCKCdnBaseBundlePack({ version, translations, createCustomCdnUrl }), ...premium && { CKEditorPremiumFeatures: createCKCdnPremiumBundlePack({ version, translations, createCustomCdnUrl }) }, ...ckbox && { CKBox: createCKBoxBundlePack(ckbox) }, loadedPlugins: combineCdnPluginsPacks(plugins ?? {}) }); return loadCKCdnResourcesPack( { ...pack, htmlAttributes: injectedHtmlElementsAttributes } ); } function validateCKEditorVersion(version) { if (isCKCdnTestingVersion(version)) { console.warn( "You are using a testing version of CKEditor 5. Please remember that it is not suitable for production environments." ); } if (!isCKCdnSupportedByEditorVersion(version)) { throw new Error( `The CKEditor 5 CDN can't be used with the given editor version: ${version}. Please make sure you are using at least the CKEditor 5 version 44.` ); } } exports.CKBOX_CDN_URL = CKBOX_CDN_URL; exports.CK_CDN_URL = CK_CDN_URL; exports.INJECTED_SCRIPTS = INJECTED_SCRIPTS; exports.INJECTED_STYLESHEETS = INJECTED_STYLESHEETS; exports.appendExtraPluginsToEditorConfig = appendExtraPluginsToEditorConfig; exports.createCKBoxCdnUrl = createCKBoxCdnUrl; exports.createCKCdnUrl = createCKCdnUrl; exports.createDefer = createDefer; exports.createIntegrationUsageDataPlugin = createIntegrationUsageDataPlugin; exports.filterBlankObjectValues = filterBlankObjectValues; exports.filterObjectValues = filterObjectValues; exports.injectScript = injectScript; exports.injectScriptsInParallel = injectScriptsInParallel; exports.injectStylesheet = injectStylesheet; exports.isCKEditorFreeLicense = isCKEditorFreeLicense; exports.isSSR = isSSR; exports.loadCKEditorCloud = loadCKEditorCloud; exports.mapObjectValues = mapObjectValues; exports.once = once; exports.overwriteArray = overwriteArray; exports.overwriteObject = overwriteObject; exports.preloadResource = preloadResource; exports.shallowCompareArrays = shallowCompareArrays; exports.uid = uid; exports.uniq = uniq; exports.waitFor = waitFor; exports.waitForWindowEntry = waitForWindowEntry; exports.without = without; Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); })); //# sourceMappingURL=index.umd.cjs.map