import { pluginSystem } from 'jodit/src/core/global';
// import { $$ } from 'jodit/src/core/helpers';
import { Dom, Plugin } from 'jodit/src/modules';
import { send, sendFiles } from 'jodit/src/modules/uploader/helpers';
import { IJodit } from 'jodit/src/types';
// import { openMultiImagePopup } from './popup/multi-image-popup';
import { watch } from 'jodit/src/core/decorators';
import './multi-image-collage.less';
/** ------------------------------------------------------------------------------
*
* 08.22 콜라주 잠들다...
*
------------------------------------------------------------------------------ */
export class MultiImageCollage extends Plugin {
// private getCollageCount = (): number => {
// const collageCount = $$('jodit-collage', this.j.editor).length;
// return collageCount;
// };
// private collageCount = 0;
@watch(':click')
protected onEditorClick(event: MouseEvent): void {
if (this.j.o.readonly) {
return;
}
const target = event.target;
if (!target) {
return;
}
if (!Dom.isTag(target, ['jodit-collage-item', 'jodit-collage'])) {
this.removeSelector();
return;
}
this.showSelector(target as HTMLElement);
}
private collageSelector = this.j.c.fromHTML(
"
"
);
private isShowSelector = false;
private showSelector = (target: HTMLElement): void => {
if (this.isShowSelector) {
this.removeSelector();
}
const { top, left, width, height } = target.getBoundingClientRect();
const { top: wrapperTop, left: wrapperLeft } =
this.j.workplace.getBoundingClientRect();
this.collageSelector.style.width = `${width}px`;
this.collageSelector.style.height = `${height}px`;
this.collageSelector.style.top = `${top - wrapperTop}px`;
this.collageSelector.style.left = `${left - wrapperLeft}px`;
this.j.workplace.appendChild(this.collageSelector);
};
private removeSelector = (): void => {
Dom.safeRemove(this.collageSelector);
};
@watch(':change')
protected onEditorChange(): void {
this.removeSelector();
}
@watch(':blur')
protected onEditorBlur(): void {
this.removeSelector();
}
getImageList = async (fileList: File[]): Promise => {
const uploadedCollageImages = await this.uploadImages(fileList);
const promises = uploadedCollageImages
.filter((item: any) => item)
.map(
(uploadedImage: any) =>
new Promise((resolve, reject) => {
const img = new Image();
img.onload = (): void => {
resolve({
width: img.naturalWidth,
height: img.naturalHeight,
url: uploadedImage.url
});
};
img.onerror = reject;
img.src = uploadedImage.url;
})
);
return await Promise.all(promises);
};
// private collageItemTemplate = (image: {
// url: string;
// width: number;
// height: number;
// collageIndex: number;
// }): string =>
// ``;
private uploadImages = async (files: File[]): Promise => {
const promises: Array> = files.map(this.sendFile);
return Promise.all(promises);
};
protected override afterInit(jodit: IJodit): void {
this.j.e.on('multiImageUploaded', async files => {
// const createCollage = async (): Promise => {
// if (files.length > 10) {
// const collageImages = files.slice(0, 10);
// const restImages = files.slice(10);
// const uploadedImages = await this.getImageList(
// collageImages
// );
// const result = this.sizeItems(uploadedImages);
// sendFiles(this.j.uploader, restImages);
// this.createCollage(result);
// } else {
// const uploadedImages = await this.getImageList(files);
// const result = this.sizeItems(uploadedImages);
// this.createCollage(result);
// }
// };
const createIndividualImages = async (): Promise => {
sendFiles(this.j.uploader, files);
};
// openMultiImagePopup(this.j, createIndividualImages, createCollage);
createIndividualImages();
this.j.e.fire('closeAllPopups');
});
// this.j.e.on('change', () => {
// this.collageCount = this.getCollageCount();
// });
// this.j.e.on('collage-item-delete', this.handleDeleteCollageItem);
}
// private handleDeleteCollageItem = (collageIndex: string): void => {
// const targetCollage = document.querySelector(
// `[data-collage-index="${collageIndex}"]`
// );
// const children = $$('jodit-collage-item', targetCollage as HTMLElement);
// if (children.length === 0) {
// this.j.s.removeNode(targetCollage as HTMLElement);
// this.j.e.fire('change');
// return;
// }
// const childrenSizes = children.map(child => {
// const { width, height } = child.style;
// const src = child.getAttribute('src') as string;
// const numberWidth = Number(width.replace('px', ''));
// const numberHeight = Number(height.replace('px', ''));
// return { width: numberWidth, height: numberHeight, url: src };
// });
// const resized = this.sizeItems(childrenSizes);
// children.forEach((child, index) => {
// child.style.width = `${resized[index].width}px`;
// child.style.height = `${resized[index].height}px`;
// });
// };
// private createCollage = (images: any[]): void => {
// const collage = (children: string): string => {
// return `${children}`;
// };
// const collageItems = images
// .map(item => ({ ...item, collageIndex: this.collageCount }))
// .map(this.collageItemTemplate)
// .join('');
// const collageHTML = collage(collageItems);
// const collageElement = this.j.c.fromHTML(collageHTML);
// this.j.s.insertHTML(collageElement);
// this.j.e.fire('change');
// this.j.e.fire('closeAllPopups');
// };
// private sizeItems = (
// items: Array<{ width: number; height: number; url: string }>
// ): any[] => {
// const twoDimensional: any[] = [];
// let index = 0;
// items.forEach(item => {
// const { width, height } = item;
// const ratio = width / height;
// if (ratio >= 2) {
// if (twoDimensional[index]?.length === 1) {
// twoDimensional[index].push(item);
// index++;
// return;
// }
// twoDimensional[index] = [item];
// index++;
// return;
// }
// if (!twoDimensional[index]) {
// twoDimensional[index] = [];
// }
// twoDimensional[index].push(item);
// if (twoDimensional[index]?.length === 2) {
// index++;
// }
// });
// const result = twoDimensional.map(array => {
// const COLLAGE_WIDTH = 855;
// const MIN_HEIGHT = 145;
// const MAX_HEIGHT = 855;
// const GAP = 5;
// const TOTAL_WIDTH = COLLAGE_WIDTH - GAP;
// if (array.length === 1) {
// return array.map((item: any) => ({
// url: item.url,
// width: COLLAGE_WIDTH,
// height: COLLAGE_WIDTH * (item.height / item.width)
// }));
// }
// const [first, second] = array;
// const firstRatio = first.width / first.height;
// const secondRatio = second.width / second.height;
// const totalRatio = firstRatio + secondRatio;
// const firstWidth = (firstRatio / totalRatio) * TOTAL_WIDTH;
// const secondWidth = (secondRatio / totalRatio) * TOTAL_WIDTH;
// const firstHeight = firstWidth / firstRatio;
// const secondHeight = secondWidth / secondRatio;
// const clampHeight = (num: number): number =>
// Math.min(Math.max(num, MIN_HEIGHT), MAX_HEIGHT);
// return [
// {
// ...first,
// width: firstWidth,
// height: clampHeight(firstHeight)
// },
// {
// ...second,
// width: secondWidth,
// height: clampHeight(secondHeight)
// }
// ];
// });
// return result.flat();
// };
protected override beforeDestruct(jodit: IJodit): void {}
private sendFile = async (file: File): Promise => {
const { o } = this.j.uploader;
const form = new FormData();
const hasRealExtension = /\.[\d\w]+$/.test(file.name);
const match_type = file.type.match(/([a-z0-9]+)\//i) as string[];
const match_extension = file.type.match(/\/([a-z0-9]+)/i) as string[];
const fileType: string =
match_type && match_type[1] ? match_type[1].toLowerCase() : '';
const fileExtension: string =
match_extension && match_extension[1]
? match_extension[1].toLowerCase()
: '';
const time = String(new Date().getTime());
let newName = file.name ? `${time}_${file.name}` : time;
if (!hasRealExtension && fileExtension) {
let extForReg = fileExtension;
if (['jpeg', 'jpg'].includes(extForReg)) {
extForReg = 'jpeg|jpg';
}
const reEnd = new RegExp('.(' + extForReg + ')$', 'i');
if (!reEnd.test(newName)) {
newName += '.' + fileExtension;
}
}
const [key, iFile, name] = o.processFileName.call(
this.j.uploader,
o.filesVariableName(fileType, fileExtension),
file,
newName
);
form.append(key, iFile, name);
return send(this.j.uploader, form).then(response => response.data);
};
}
pluginSystem.add('multi-image-collage', MultiImageCollage);