@limetech/lime-elements
Version:
168 lines (167 loc) • 4.56 kB
JavaScript
import translate from '../../../../../global/translations';
export const imageCache = new Map();
/**
*
* @param language
*/
export function getImageNode(language) {
return { image: createImageNodeSpec(language) };
}
/**
*
* @param language
*/
export function getImageNodeMarkdownSerializer(language) {
return { image: createImageNodeMarkdownSerializer(language) };
}
/**
*
* @param img
* @param node
*/
export function applyImageStyles(img, node) {
img.style.height = node.attrs.height;
img.style.width = node.attrs.width;
img.style.minHeight = node.attrs.minHeight;
img.style.minWidth = node.attrs.minWidth;
img.style.maxWidth = node.attrs.maxWidth;
}
/**
* Recursively checks if a ProseMirror node or
* any of its child nodes is an image node.
* @param node
*/
export function hasImageNode(node) {
if (node.type.name === 'image') {
return true;
}
for (let i = 0; i < node.childCount; i++) {
const childNode = node.child(i);
if (hasImageNode(childNode)) {
return true;
}
}
return false;
}
function createImageNodeMarkdownSerializer(language) {
return (markdownSerializerState, node) => {
const state = node.attrs.state;
if (!isEditorImageState(state)) {
return;
}
if (state === 'success') {
const imageHTML = getImageHTML(node.attrs);
markdownSerializerState.write(imageHTML);
return;
}
const statusHTML = getStatusHTML(state, node.attrs.alt, language);
markdownSerializerState.write(statusHTML);
};
}
function getStatusHTML(state, alt, language) {
const key = state === 'failed' ? 'failed' : 'loading';
const text = translate.get(`editor-image-view.${key}`, language, {
filename: alt || 'file',
});
return `<span>${text}</span>`;
}
function getImageHTML(attrs) {
const style = [];
if (attrs.height) {
style.push(`height: ${attrs.height};`);
}
if (attrs.width) {
style.push(`width: ${attrs.width};`);
}
if (attrs.minHeight) {
style.push(`min-height: ${attrs.minHeight};`);
}
if (attrs.minWidth) {
style.push(`min-width: ${attrs.minWidth};`);
}
if (attrs.maxWidth) {
style.push(`max-width: ${attrs.maxWidth};`);
}
const styleAttribute = style.length > 0 ? ` style="${style.join('')}"` : '';
return `<img src="${attrs.src}" alt="${attrs.alt}"${styleAttribute} />`;
}
function createImageNodeSpec(language) {
return {
group: 'inline',
inline: true,
attrs: {
src: { default: '' },
alt: { default: '' },
fileInfoId: { default: '' },
height: { default: '' },
width: { default: '' },
minHeight: { default: '' },
minWidth: { default: '' },
maxWidth: { default: '100%' },
state: { default: 'success' },
},
toDOM: (node) => {
if (!isEditorImageState(node.attrs.state)) {
return;
}
if (node.attrs.state === 'success') {
return getOrCreateImageElement(node.attrs.fileInfoId, node);
}
return createStatusSpanForState(node.attrs.state, node, language);
},
parseDOM: [
{
tag: 'img',
getAttrs: (dom) => {
return {
src: dom.getAttribute('src') || '',
alt: dom.getAttribute('alt') || 'file',
width: dom.style.width || '',
maxWidth: '100%',
state: 'success',
fileInfoId: crypto.randomUUID(),
};
},
},
],
};
}
function isEditorImageState(state) {
return state === 'loading' || state === 'failed' || state === 'success';
}
function getOrCreateImageElement(fileInfoId, node) {
let img = imageCache.get(fileInfoId);
if (img) {
updateImageElement(img, node);
}
else {
img = createImageElement(node);
imageCache.set(fileInfoId, img);
}
return img;
}
function createStatusSpanForState(state, node, language) {
const statusKey = state === 'failed' ? 'failed' : 'loading';
return createStatusSpan(statusKey, node, language);
}
function createStatusSpan(key, node, language) {
const text = translate.get(`editor-image-view.${key}`, language, {
filename: node.attrs.alt || 'file',
});
const span = document.createElement('span');
span.textContent = text;
return span;
}
function updateImageElement(img, node) {
img.alt = node.attrs.alt;
applyImageStyles(img, node);
return img;
}
function createImageElement(node) {
const img = document.createElement('img');
img.src = node.attrs.src;
img.alt = node.attrs.alt;
applyImageStyles(img, node);
return img;
}
//# sourceMappingURL=node.js.map