Open pamapa opened 2 years ago
If needed by others, we are using this something like this:
function InjectAccessTokenPlugin(editor: ClassicEditor) {
const re = new RegExp(`${YOUR_API_URL}.+`);
// https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/conversion/helpers/downcast.html
// https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_conversion_conversion-Conversion.html
editor.conversion.for("editingDowncast")
.add((dispatcher: DowncastDispatcher) => dispatcher.on<`attribute:src${string}`>("attribute:src", (event, data, conversionApi) => {
if (event.name !== "attribute:src:imageInline" && event.name !== "attribute:src:imageBlock") {
return;
}
if (!data.attributeKey) {
return;
}
conversionApi.consumable.consume(data.item, event.name);
const viewWriter = conversionApi.writer;
const viewElement = conversionApi.mapper.toViewElement(data.item);
if (!viewElement) {
console.warn("toViewElement failed", data.item);
return;
}
let img = viewElement;
// console.log("viewElement", viewElement);
if (viewElement.name !== "img") {
// imageBlock: <figure><img></figure>
// imageInline: <span><img></span>
const tmp = viewElement.getChild(0);
if (!tmp || !tmp.is("element") || tmp.name !== "img") {
console.warn("figure/span has no img", viewElement, tmp);
return;
}
img = tmp;
}
if (data.attributeNewValue && typeof data.attributeNewValue === "string") {
let src: string;
if (re.exec(data.attributeNewValue)) {
// Fetching is async, the display is not instant. It displays the image as soon as you click on the editor
// custom_fetch: fetch with access token (bearer) in header and returns blob
custom_fetch(data.attributeNewValue, { method: "GET" }).then((response) => {
src = URL.createObjectURL(response.blob);
refImageSrc.current.push(src);
// view.change to update ckeditor5
// https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-image/src/imageupload/imageuploadprogress.js
editor.editing.view.change(() => {
viewWriter.setAttribute(data.attributeKey || "", src, img);
});
}).catch((e) => {
console.error(e);
});
} else {
console.log("src is no api attachment url", data.attributeNewValue, YOUR_API_URL);
src = data.attributeNewValue;
}
} else {
viewWriter.removeAttribute(data.attributeKey, img);
}
// console.log("downcastImage end", img);
}));
}
...
<CKEditor
...
config={{
extraPlugins: [
InjectAccessTokenPlugin
]
...
Not sure this issue already be resolved but we're struggling it, too. The same, we have a back-end api call during editing downcasting and the result what I see is I can see the Get request has been send and got the 200 OK reply, but the image still blank but got show when I click it. @pamapa just wondering if you got any way to workaround this or some useful solution, please update here, that would be very helpful, thx!
@ScottPony we are still using the InjectAccessTokenPlugin
, which is posted above, works like a charm...
@pamapa do you mind if you can share the update sample code in typescript and how to use it?
📝 Provide a description of requested docs changes
What is the purpose and what should be changed? Would be nice to have a documentation about the correct way to view images, which need additional authorization to access. For uploading images there is already support for this (e.g. https://ckeditor.com/docs/ckeditor5/latest/features/image-upload/simple-upload-adapter.html). When uploading images it is possible to add e.g. an authorization header containing the access token. How to achieve the same when requesting/viewing images?
I assume to achieve the same with requesting/viewing images, we need to implement an
DowncastDispatcher
onattribute:src
(https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/conversion/conversion-preserving-custom-content.html). In this customDowncastDispatcher
we either append the token in the URL (tok=123
, ugly solution) or fetch the image including authorization header and append the received blob viacreateObjectURL
. I currently face the problem, that the second approach needs an async fetch, when the editor is initially loaded, this image is not showed, but as soon as the editor text gets touched it shows up. I guess we need to fire a special event?Would be really nice to have this feature documented, as we are not the only one which needs that feature.