123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- let MaterialEditor = (function () {
- let module = {};
- let __CreateNewsButton = document.querySelector("#CreateNewsButton");
- if (__CreateNewsButton) {
- __CreateNewsButton.onclick = openModal;
- }
- let __CreateNoticeButton = document.querySelector("#CreateNoticeButton");
- if (__CreateNoticeButton) {
- __CreateNoticeButton.onclick = openModal;
- }
- let __CreateMaterialButton = document.querySelector("#CreateMaterialButton");
- if (__CreateMaterialButton) {
- __CreateMaterialButton.onclick = openModal;
- }
- let __CurrentCategory = undefined;
- function dataURIToBlob(dataURI) {
- const splitDataURI = dataURI.split(",");
- const byteString = splitDataURI[0].indexOf("base64") >= 0 ? atob(splitDataURI[1]) : decodeURI(splitDataURI[1]);
- const mimeString = splitDataURI[0].split(":")[1].split(";")[0];
- const ia = new Uint8Array(byteString.length);
- for (let i = 0; i < byteString.length; i++) ia[i] = byteString.charCodeAt(i);
- return new Blob([ia], { type: mimeString });
- }
- /**
- * Собрать все данные и отправить на БД
- *
- * @param {HTMLInputElement} caption
- * @param {HTMLInputElement} link
- * @param {HTMLDivElement} content
- * @param {HTMLDivElement} images
- * @param {HTMLInputElement} file
- */
- function create(caption, link, content, images, file) {
- if (!caption || !link || !content || !images) {
- Messenger.Show("Некоторые элементы не были найдены, невозможно создать новость!");
- return;
- }
- if (caption.value.length == 0) {
- Messenger.Show("Необходимо заполнить заголовок!");
- return;
- }
- if (link.value.length == 0) {
- link.value = Main.GenerateHash256();
- }
- let preview = {
- Valid: true,
- String: "",
- };
- var date = new Date();
- let m = ("00" + (date.getMonth() + 1)).slice(-2);
- let d = ("00" + date.getDate()).slice(-2);
- var imageFullpath = "image/" + __CurrentCategory + "/" + date.getUTCFullYear().toString() + "-" + m + "-" + d + "/";
- var thumbFullpath = "thumb/" + __CurrentCategory + "/" + date.getUTCFullYear().toString() + "-" + m + "-" + m + "/";
- let data = new FormData();
- let contentHtml = "";
- for (const c of content.blocks) {
- switch (c.type) {
- case "paragraph":
- contentHtml += "<p>" + c.data.text + "</p>";
- preview.String += c.data.text;
- break;
- case "header":
- contentHtml += "<h" + c.data.level + ">" + c.data.text + "/h" + c.data.level + ">";
- preview.String += c.data.text;
- break;
- case "list":
- if (c.data.style === "ordered") {
- contentHtml += "<ol>";
- for (const li of c.data.items) {
- contentHtml += "<li>" + li + "</li>";
- preview.String += li;
- }
- contentHtml += "</ol>";
- } else {
- contentHtml += "<ul>";
- for (const li of c.data.items) {
- contentHtml += "<li>" + li + "</li>";
- preview.String += li;
- }
- contentHtml += "</ul>";
- }
- break;
- case "delimiter":
- contentHtml += "<hr>";
- break;
- case "table":
- contentHtml += "<table>";
- for (const row of c.data.content) {
- contentHtml += "<tr>";
- for (const col of row) {
- contentHtml += "<td>" + col + "</td>";
- preview.String += col;
- }
- contentHtml += "</tr>";
- }
- contentHtml += "</table>";
- break;
- case "image":
- let filename = Main.GenerateHashDashed(2) + "." + c.data.url.slice(11, c.data.url.indexOf(";"));
- contentHtml +=
- '<a href="/' +
- imageFullpath +
- filename +
- '" data-fslightbox="' +
- link.value +
- '"><img class="material-image" src="/' +
- thumbFullpath +
- filename +
- '" /></a>';
- let div = document.createElement("div");
- div.innerHTML = c.data.caption;
- if (div.textContent.length > 0) {
- contentHtml += '<div class="material-image-caption">' + c.data.caption + "</div>";
- }
- data.append("Files", dataURIToBlob(c.data.url), filename);
- break;
- }
- }
- let clearTags = document.createElement("div");
- clearTags.innerHTML = preview.String;
- preview.String = clearTags.textContent;
- if (preview.String.length > 260) {
- preview.String = preview.String.slice(0, 260);
- }
- let selectedImage = {
- Valid: false,
- String: "",
- };
- if (__CurrentCategory != MATERIAL_CATEGORY.MATERIAL) {
- let selectedImageName = ";";
- let selectedInput = images.querySelector("input:checked");
- if (selectedInput) {
- let img = selectedInput.closest(".image").querySelector("img");
- if (img) {
- selectedImageName = img.alt;
- selectedImage.String = thumbFullpath + selectedImageName.toLowerCase();
- selectedImage.Valid = true;
- }
- }
- if (file.files.length > 0) {
- if (__CurrentCategory != MATERIAL_CATEGORY.NOTICE) {
- contentHtml += '<div class="news-images">';
- }
- for (const f of file.files) {
- let filename = f.name.toLowerCase();
- filename = Main.GenerateHashDashed(2) + filename.slice(filename.lastIndexOf("."));
- if (selectedImageName === f.name) {
- selectedImage.String = thumbFullpath + filename;
- }
- if (__CurrentCategory != MATERIAL_CATEGORY.NOTICE) {
- contentHtml +=
- '<a href="/' +
- imageFullpath +
- filename +
- '" data-fslightbox="' +
- link.value +
- '"><img src="/' +
- thumbFullpath +
- filename +
- '" alt="' +
- filename +
- '"></a>';
- }
- data.append("Files", f, filename);
- }
- if (__CurrentCategory != MATERIAL_CATEGORY.NOTICE) {
- contentHtml += "</div>";
- }
- }
- }
- data.set("Caption", caption.value);
- data.set("Link", link.value);
- data.set("Content", contentHtml);
- data.set("Source", JSON.stringify(content));
- data.set("PreviewValid", preview.Valid);
- data.set("PreviewString", preview.String);
- data.set("ImageValid", selectedImage.Valid);
- data.set("ImageString", selectedImage.String);
- data.set("ImagePath", imageFullpath);
- data.set("ThumbPath", thumbFullpath);
- let closeModal = this.closest(".modal").querySelector(".close");
- XHR.POST(
- function (result) {
- if (result && "Error" in result) {
- if (result.Error === null) {
- Messenger.Show(__CurrentCategory + " успешно добавлена");
- closeModal.click();
- } else {
- Messenger.Show("Возникла ошибка добавления новости." + result.Error);
- }
- }
- },
- "/material-insert/" + __CurrentCategory,
- data,
- null,
- true,
- true
- );
- }
- /**
- * Создать модальное окно для добавления новости
- */
- function openModal() {
- switch (this.dataset.category) {
- case MATERIAL_CATEGORY.MATERIAL:
- __CurrentCategory = MATERIAL_CATEGORY.MATERIAL;
- break;
- case MATERIAL_CATEGORY.NEWS:
- __CurrentCategory = MATERIAL_CATEGORY.NEWS;
- break;
- case MATERIAL_CATEGORY.NOTICE:
- __CurrentCategory = MATERIAL_CATEGORY.NOTICE;
- break;
- default:
- return;
- }
- let body = document.createElement("div"),
- inputCaption = document.createElement("input"),
- inputLink = document.createElement("input"),
- contentBlock = document.createElement("div"),
- previewBlock = document.createElement("div"),
- preview = document.createElement("div"),
- label = document.createElement("label"),
- file = document.createElement("input"),
- fileButton = document.createElement("div"),
- buttonSend = document.createElement("button");
- label.append(file, fileButton);
- label.className = "select-file";
- fileButton.className = "button";
- fileButton.textContent = "Выбрать изображениия";
- file.type = "file";
- if (__CurrentCategory === MATERIAL_CATEGORY.NOTICE) {
- file.multiple = false;
- } else {
- file.multiple = true;
- }
- file.accept = "image/*";
- file.onchange = changeImages;
- inputCaption.type = "text";
- inputCaption.placeholder = "Заголовок/название (обязательно)";
- inputLink.type = "text";
- inputLink.placeholder = "Ссылка на " + __CurrentCategory + " (не обязательно)";
- buttonSend.textContent = "Создать";
- // buttonSend.onclick = create.bind(buttonSend, inputCaption, inputLink, contentBlock, preview, file);
- preview.className = "preview-images";
- contentBlock.id = "editorjs";
- contentBlock.className = "content-editor";
- // contentBlock.append(createManipulator());
- if (__CurrentCategory !== MATERIAL_CATEGORY.MATERIAL) {
- body.append(inputCaption, inputLink, contentBlock, previewBlock, label, preview, buttonSend);
- } else {
- body.append(inputCaption, inputLink, contentBlock, previewBlock, buttonSend);
- }
- let tools = {
- header: {
- class: Header,
- inlineToolbar: true,
- config: {
- placeholder: "Заголовок",
- },
- shortcut: "CMD+SHIFT+H",
- },
- list: {
- class: List,
- inlineToolbar: true,
- shortcut: "CMD+SHIFT+L",
- },
- // quote: {
- // class: Quote,
- // inlineToolbar: true,
- // config: {
- // quotePlaceholder: "Введите цитату",
- // captionPlaceholder: "Автор цитаты",
- // },
- // shortcut: "CMD+SHIFT+O",
- // },
- marker: {
- class: Marker,
- shortcut: "CMD+SHIFT+M",
- },
- delimiter: Delimiter,
- inlineCode: {
- class: InlineCode,
- shortcut: "CMD+SHIFT+C",
- },
- linkTool: LinkTool,
- table: {
- class: Table,
- inlineToolbar: true,
- shortcut: "CMD+ALT+T",
- },
- onReady: function () {
- console.log("ready");
- },
- onChange: function () {
- console.log("changed");
- },
- };
- if (__CurrentCategory === MATERIAL_CATEGORY.MATERIAL) {
- tools.image = {
- class: SimpleImage,
- inlineCode: true,
- };
- tools.embed = {
- class: Embed,
- inlineToolbar: false,
- config: {
- services: {
- youtube: true,
- },
- },
- };
- }
- const editor = new EditorJS({
- holderOd: "editorjs",
- tools: tools,
- data: null,
- });
- buttonSend.addEventListener("click", function () {
- editor.save().then((savedData) => {
- create.call(buttonSend, inputCaption, inputLink, savedData, preview, file);
- });
- });
- Modal.Create("Создать " + __CurrentCategory, body);
- }
- /**
- * Функция выбора файлов изображения для новости
- */
- function changeImages() {
- let preview = document.querySelector(".preview-images");
- if (!preview) {
- console.warn("Элемент [.preview-images] не найжен");
- return;
- }
- for (const file of this.files) {
- /**
- * 1. Контейнер под изображение
- */
- let div = document.createElement("div");
- div.className = "image";
- /**
- * 2. Создать элемент для изображения
- */
- let img = document.createElement("img");
- img.src = window.URL.createObjectURL(file);
- img.alt = file.name;
- img.height = 100;
- /**
- * 3. Создать label
- */
- let label = document.createElement("label");
- /**
- * 4. Создать input + span
- */
- let input = document.createElement("input");
- input.type = "radio";
- input.dataset.image = file.name;
- input.name = "preview-images";
- let span = document.createElement("span");
- div.append(img, label);
- label.append(input, span);
- preview.append(div);
- }
- let firstImage = preview.querySelector("input");
- firstImage.click();
- }
- return module;
- })();
|