@ckeditor/ckeditor5-vue
Version:
Official Vue.js 3+ component for CKEditor 5 – the best browser-based rich text editor.
214 lines (213 loc) • 7.13 kB
JavaScript
import * as Vue from "vue";
import { version, defineComponent, mergeModels, useModel, ref, watch, onMounted, markRaw, onBeforeUnmount, openBlock, createBlock, resolveDynamicComponent, computed, watchEffect, shallowReadonly, toValue } from "vue";
import { debounce } from "lodash-es";
import { createIntegrationUsageDataPlugin, isCKEditorFreeLicense, appendExtraPluginsToEditorConfig, uid, loadCKEditorCloud } from "@ckeditor/ckeditor5-integrations-common";
import { loadCKEditorCloud as loadCKEditorCloud2 } from "@ckeditor/ckeditor5-integrations-common";
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
const VueIntegrationUsageDataPlugin = createIntegrationUsageDataPlugin(
"vue",
{
version: "7.3.0",
frameworkVersion: version
}
);
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
function appendAllIntegrationPluginsToConfig(editorConfig) {
if (isCKEditorFreeLicense(editorConfig.licenseKey)) {
return editorConfig;
}
return appendExtraPluginsToEditorConfig(editorConfig, [
/**
* This part of the code is not executed in open-source implementations using a GPL key.
* It only runs when a specific license key is provided. If you are uncertain whether
* this applies to your installation, please contact our support team.
*/
VueIntegrationUsageDataPlugin
]);
}
const VUE_INTEGRATION_READ_ONLY_LOCK_ID = "Lock from Vue integration (@ckeditor/ckeditor5-vue)";
const INPUT_EVENT_DEBOUNCE_WAIT = 300;
const _sfc_main = /* @__PURE__ */ defineComponent({
...{
name: "CKEditor"
},
__name: "ckeditor",
props: /* @__PURE__ */ mergeModels({
editor: {},
config: { default: () => ({}) },
tagName: { default: "div" },
disabled: { type: Boolean, default: false },
disableTwoWayDataBinding: { type: Boolean, default: false }
}, {
"modelValue": { type: String, default: "" },
"modelModifiers": {}
}),
emits: /* @__PURE__ */ mergeModels(["ready", "destroy", "blur", "focus", "input", "update:modelValue"], ["update:modelValue"]),
setup(__props, { expose: __expose, emit: __emit }) {
const model = useModel(__props, "modelValue");
const props = __props;
const emit = __emit;
const element = ref();
const instance = ref();
const lastEditorData = ref();
__expose({
instance,
lastEditorData
});
watch(model, (newModel) => {
if (instance.value && newModel !== lastEditorData.value) {
instance.value.data.set(newModel);
}
});
watch(() => props.disabled, (readOnlyMode) => {
if (readOnlyMode) {
instance.value.enableReadOnlyMode(VUE_INTEGRATION_READ_ONLY_LOCK_ID);
} else {
instance.value.disableReadOnlyMode(VUE_INTEGRATION_READ_ONLY_LOCK_ID);
}
});
function checkVersion() {
const version2 = window.CKEDITOR_VERSION;
if (!version2) {
return console.warn('Cannot find the "CKEDITOR_VERSION" in the "window" scope.');
}
const [major] = version2.split(".").map(Number);
if (major >= 42 || version2.startsWith("0.0.0")) {
return;
}
console.warn("The <CKEditor> component requires using CKEditor 5 in version 42+ or nightly build.");
}
function setUpEditorEvents(editor) {
const emitDebouncedInputEvent = debounce((evt) => {
if (props.disableTwoWayDataBinding) {
return;
}
const data = lastEditorData.value = editor.data.get();
emit("update:modelValue", data, evt, editor);
emit("input", data, evt, editor);
}, INPUT_EVENT_DEBOUNCE_WAIT, { leading: true });
editor.model.document.on("change:data", emitDebouncedInputEvent);
editor.editing.view.document.on("focus", (evt) => {
emit("focus", evt, editor);
});
editor.editing.view.document.on("blur", (evt) => {
emit("blur", evt, editor);
});
}
checkVersion();
onMounted(() => {
const editorConfig = appendAllIntegrationPluginsToConfig(
Object.assign({}, props.config)
);
if (model.value) {
editorConfig.initialData = model.value;
}
props.editor.create(element.value, editorConfig).then((editor) => {
instance.value = markRaw(editor);
setUpEditorEvents(editor);
if (model.value !== editorConfig.initialData) {
editor.data.set(model.value);
}
if (props.disabled) {
editor.enableReadOnlyMode(VUE_INTEGRATION_READ_ONLY_LOCK_ID);
}
emit("ready", editor);
}).catch((error) => {
console.error(error);
});
});
onBeforeUnmount(() => {
if (instance.value) {
instance.value.destroy();
instance.value = void 0;
}
emit("destroy");
});
return (_ctx, _cache) => {
return openBlock(), createBlock(resolveDynamicComponent(_ctx.tagName), {
ref_key: "element",
ref: element
}, null, 512);
};
}
});
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
const useAsync = (asyncFunc) => {
const lastQueryUUID = ref(null);
const error = ref(null);
const data = ref(null);
const loading = computed(() => lastQueryUUID.value !== null);
watchEffect(async () => {
const currentQueryUID = uid();
lastQueryUUID.value = currentQueryUID;
data.value = null;
error.value = null;
const shouldDiscardQuery = () => lastQueryUUID.value !== currentQueryUID;
try {
const result = await asyncFunc();
if (!shouldDiscardQuery()) {
data.value = result;
}
} catch (err) {
if (!shouldDiscardQuery()) {
error.value = err;
}
} finally {
if (!shouldDiscardQuery()) {
lastQueryUUID.value = null;
}
}
});
return {
loading: shallowReadonly(loading),
data: shallowReadonly(data),
error: shallowReadonly(error)
};
};
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
function useCKEditorCloud(config) {
return useAsync(
() => loadCKEditorCloud(
toValue(config)
)
);
}
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
/* istanbul ignore if -- @preserve */
if (!Vue.version || !Vue.version.startsWith("3.")) {
throw new Error(
"The CKEditor plugin works only with Vue 3+. For more information, please refer to https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/vuejs-v3.html"
);
}
const CkeditorPlugin = {
/**
* Installs the plugin, registering the `<ckeditor>` component.
*
* @param app The application instance.
*/
install(app) {
app.component("Ckeditor", _sfc_main);
}
};
export {
_sfc_main as Ckeditor,
CkeditorPlugin,
loadCKEditorCloud2 as loadCKEditorCloud,
useCKEditorCloud
};
//# sourceMappingURL=ckeditor.js.map