From cb8adee7deb9f6cfdbaf4c28668b7e105c698591 Mon Sep 17 00:00:00 2001 From: stephanie rousset Date: Wed, 6 Nov 2024 15:30:24 +0100 Subject: [PATCH] fix: override editor js in decidim_awesome --- .../decidim/decidim_awesome/editors/editor.js | 214 ++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 app/packs/src/decidim/decidim_awesome/editors/editor.js diff --git a/app/packs/src/decidim/decidim_awesome/editors/editor.js b/app/packs/src/decidim/decidim_awesome/editors/editor.js new file mode 100644 index 0000000000..7bec3c9396 --- /dev/null +++ b/app/packs/src/decidim/decidim_awesome/editors/editor.js @@ -0,0 +1,214 @@ +/* eslint-disable require-jsdoc, func-style */ + +/* +* Since version 0.25 we follow a different strategy and opt to destroy and override completely the original editor +* That's because editors are instantiated directly instead of creating a global function to instantiate them +*/ + +import lineBreakButtonHandler from "src/decidim/editor/linebreak_module" +import InscrybMDE from "inscrybmde" +import Europa from "europa" +import "inline-attachment/src/inline-attachment"; +import "inline-attachment/src/codemirror-4.inline-attachment"; +import "inline-attachment/src/jquery.inline-attachment"; +import hljs from "highlight.js"; +import "highlight.js/styles/github.css"; +import "src/decidim/editor/clipboard_override" +import "src/decidim/vendor/image-resize.min" +import "src/decidim/vendor/image-upload.min" +import { marked } from "marked"; + +const DecidimAwesome = window.DecidimAwesome || {}; +const quillFormats = ["bold", "italic", "link", "underline", "header", "list", "video", "image", "alt", "break", "width", "style", "code", "blockquote", "indent"]; + +// A tricky way to destroy the quill editor +export function destroyQuillEditor(container) { + if (container) { + const content = $(container).find(".ql-editor").html(); + $(container).html(content); + $(container).siblings(".ql-toolbar").remove(); + $(container).find("*[class*='ql-']").removeClass((index, className) => (className.match(/(^|\s)ql-\S+/g) || []).join(" ")); + $(container).removeClass((index, className) => (className.match(/(^|\s)ql-\S+/g) || []).join(" ")); + if ($(container).next().is("p.help-text")) { + $(container).next().remove(); + } + } + else { + console.error(`editor [${container}] not exists`); + } +} + +export function createQuillEditor(container) { + const toolbar = $(container).data("toolbar"); + const disabled = $(container).data("disabled"); + const allowedEmptyContentSelector = "iframe,img"; + + let quillToolbar = [ + ["bold", "italic", "underline", "linebreak"], + [{ list: "ordered" }, { list: "bullet" }], + ["link", "clean"], + ["code", "blockquote"], + [{ "indent": "-1"}, { "indent": "+1" }] + ]; + + let addImage = false; + + if (toolbar === "full") { + quillToolbar = [ + [{ header: [2, 3, 4, 5, 6, false] }], + ...quillToolbar + ]; + if (DecidimAwesome.allow_images_in_full_editor) { + quillToolbar.push(["video", "image"]); + addImage = true; + } else { + quillToolbar.push(["video"]); + } + } else if (toolbar === "basic") { + if (DecidimAwesome.allow_images_in_small_editor) { + quillToolbar.push(["video", "image"]); + addImage = true; + } else { + quillToolbar.push(["video"]); + } + } else if (DecidimAwesome.allow_images_in_small_editor) { + quillToolbar.push(["image"]); + addImage = true; + } + + let modules = { + linebreak: {}, + toolbar: { + container: quillToolbar, + handlers: { + "linebreak": lineBreakButtonHandler + } + } + }; + + const $input = $(container).siblings('input[type="hidden"]'); + container.innerHTML = $input.val() || ""; + const token = $('meta[name="csrf-token"]').attr("content"); + if (addImage) { + modules.imageResize = { + modules: ["Resize", "DisplaySize"] + } + modules.imageUpload = { + url: DecidimAwesome.editor_uploader_path, + method: "POST", + name: "image", + withCredentials: false, + headers: { "X-CSRF-Token": token }, + callbackOK: (serverResponse, next) => { + $("div.ql-toolbar").last().removeClass("editor-loading") + next(serverResponse.url); + }, + callbackKO: (serverError) => { + $("div.ql-toolbar").last().removeClass("editor-loading") + let msg = serverError && serverError.body; + try { + msg = JSON.parse(msg).message; + } catch (evt) { console.error("Parsing error", evt); } + console.error(`Image upload error: ${msg}`); + let $p = $(`

${msg}

`); + $(container).after($p) + setTimeout(() => { + $p.fadeOut(1000, () => { + $p.destroy(); + }); + }, 3000); + }, + checkBeforeSend: (file, next) => { + $("div.ql-toolbar").last().addClass("editor-loading") + next(file); + } + } + } + const quill = new Quill(container, { + modules: modules, + formats: quillFormats, + theme: "snow" + }); + + if (disabled) { + quill.disable(); + } + + quill.on("text-change", () => { + const text = quill.getText(); + + // Triggers CustomEvent with the cursor position + // It is required in input_mentions.js + let event = new CustomEvent("quill-position", { + detail: quill.getSelection() + }); + container.dispatchEvent(event); + + if ((text === "\n" || text === "\n\n") && quill.root.querySelectorAll(allowedEmptyContentSelector).length === 0 + && !$input.val().match(/img/)) { + $input.val(""); + } else { + const emptyParagraph = "


"; + const cleanHTML = quill.root.innerHTML.replace( + new RegExp(`^${emptyParagraph}|${emptyParagraph}$`, "g"), + "" + ); + $input.val(cleanHTML); + } + }); + // After editor is ready, linebreak_module deletes two extraneous new lines + quill.emitter.emit("editor-ready"); + + if (addImage) { + const text = $(container).data("dragAndDropHelpText") || DecidimAwesome.texts.drag_and_drop_image; + $(container).after(`

${text}

`); + } + + // After editor is ready, linebreak_module deletes two extraneous new lines + quill.emitter.emit("editor-ready"); + + return quill; +} + +export function createMarkdownEditor(container) { + const text = DecidimAwesome.texts.drag_and_drop_image; + const token = $('meta[name="csrf-token"]').attr("content"); + const $input = $(container).siblings('input[type="hidden"]'); + const $faker = $('