import { createConfigurationFor, Features } from "./Ckeditor/Configuration";
import { dispatchToCkeditor } from "./Ckeditor/Event";
import { setup as setupSubmitOnEnter } from "./Ckeditor/SubmitOnEnter";
-import { normalizeLegacyMessage } from "./Ckeditor/Cleanup";
+import { normalizeLegacyMessage } from "./Ckeditor/Normalizer";
import Devtools from "../Devtools";
import { ClassicEditor, EditorConfig, Element as CkeElement } from "./Ckeditor/Types";
+++ /dev/null
-/**
- * Cleans up the markup of legacy messages.
- *
- * Messages created in the previous editor used empty paragraphs to create empty
- * lines. In addition, Firefox kept trailing <br> in lines with content, which
- * causes issues with CKEditor.
- *
- * @author Alexander Ebert
- * @copyright 2001-2023 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @since 6.0
- */
-
-import DomUtil from "../../Dom/Util";
-
-function normalizeBr(div: HTMLElement): void {
- div.querySelectorAll("br").forEach((br) => {
- unwrapBr(br);
- removeTrailingBr(br);
- });
-}
-
-function unwrapBr(br: HTMLElement): void {
- for (;;) {
- if (br.previousSibling || br.nextSibling) {
- return;
- }
-
- const parent = br.parentElement!;
- switch (parent.tagName) {
- case "B":
- case "DEL":
- case "EM":
- case "I":
- case "STRONG":
- case "SUB":
- case "SUP":
- case "SPAN":
- case "U":
- parent.insertAdjacentElement("afterend", br);
- parent.remove();
- break;
-
- default:
- return;
- }
- }
-}
-
-function removeTrailingBr(br: HTMLElement): void {
- if (br.dataset.ckeFiller === "true") {
- return;
- }
-
- const paragraphOrTableCell = br.closest("p, td");
- if (paragraphOrTableCell === null) {
- return;
- }
-
- if (!DomUtil.isAtNodeEnd(br, paragraphOrTableCell)) {
- return;
- }
-
- if (paragraphOrTableCell.tagName === "TD" || paragraphOrTableCell.childNodes.length > 1) {
- br.remove();
- }
-}
-
-function getPossibleSpacerParagraphs(div: HTMLElement): HTMLParagraphElement[] {
- const paragraphs: HTMLParagraphElement[] = [];
-
- div.querySelectorAll("p").forEach((paragraph) => {
- paragraph.normalize();
-
- if (paragraph.childNodes.length === 1) {
- const child = paragraph.childNodes[0];
- if (child instanceof HTMLBRElement && child.dataset.ckeFiller !== "true") {
- paragraphs.push(paragraph);
- }
- }
- });
-
- return paragraphs;
-}
-
-function reduceSpacerParagraphs(paragraphs: HTMLParagraphElement[]): void {
- if (paragraphs.length === 0) {
- return;
- }
-
- for (let i = 0, length = paragraphs.length; i < length; i++) {
- const candidate = paragraphs[i];
- let offset = 0;
-
- // Searches for adjacent paragraphs.
- while (i + offset + 1 < length) {
- const nextCandidate = paragraphs[i + offset + 1];
- if (candidate.nextElementSibling !== nextCandidate) {
- break;
- }
-
- offset++;
- }
-
- if (offset === 0) {
- // An offset of 0 means that this is a single paragraph and we
- // can safely remove it.
- candidate.remove();
- } else {
- // We need to reduce the number of paragraphs by half, unless it
- // is an uneven number in which case we need to remove one
- // additional paragraph.
- const totalNumberOfParagraphs = offset + 1;
- const numberOfParagraphsToRemove = Math.ceil(totalNumberOfParagraphs / 2);
-
- const removeParagraphs = paragraphs.slice(i, i + numberOfParagraphsToRemove);
- removeParagraphs.forEach((paragraph) => {
- paragraph.remove();
- });
-
- i += offset;
- }
- }
-}
-
-export function normalizeLegacyMessage(element: HTMLElement): void {
- if (!(element instanceof HTMLTextAreaElement)) {
- throw new TypeError("Expected the element to be a <textarea>.");
- }
-
- const div = document.createElement("div");
- div.innerHTML = element.value;
-
- normalizeBr(div);
- const paragraphs = getPossibleSpacerParagraphs(div);
- reduceSpacerParagraphs(paragraphs);
-
- element.value = div.innerHTML;
-}
--- /dev/null
+/**
+ * Cleans up the markup of legacy messages.
+ *
+ * Messages created in the previous editor used empty paragraphs to create empty
+ * lines. In addition, Firefox kept trailing <br> in lines with content, which
+ * causes issues with CKEditor.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2023 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @since 6.0
+ */
+
+import DomUtil from "../../Dom/Util";
+
+function normalizeBr(div: HTMLElement): void {
+ div.querySelectorAll("br").forEach((br) => {
+ unwrapBr(br);
+ removeTrailingBr(br);
+ });
+}
+
+function unwrapBr(br: HTMLElement): void {
+ for (;;) {
+ if (br.previousSibling || br.nextSibling) {
+ return;
+ }
+
+ const parent = br.parentElement!;
+ switch (parent.tagName) {
+ case "B":
+ case "DEL":
+ case "EM":
+ case "I":
+ case "STRONG":
+ case "SUB":
+ case "SUP":
+ case "SPAN":
+ case "U":
+ parent.insertAdjacentElement("afterend", br);
+ parent.remove();
+ break;
+
+ default:
+ return;
+ }
+ }
+}
+
+function removeTrailingBr(br: HTMLElement): void {
+ if (br.dataset.ckeFiller === "true") {
+ return;
+ }
+
+ const paragraphOrTableCell = br.closest("p, td");
+ if (paragraphOrTableCell === null) {
+ return;
+ }
+
+ if (!DomUtil.isAtNodeEnd(br, paragraphOrTableCell)) {
+ return;
+ }
+
+ if (paragraphOrTableCell.tagName === "TD" || paragraphOrTableCell.childNodes.length > 1) {
+ br.remove();
+ }
+}
+
+function getPossibleSpacerParagraphs(div: HTMLElement): HTMLParagraphElement[] {
+ const paragraphs: HTMLParagraphElement[] = [];
+
+ div.querySelectorAll("p").forEach((paragraph) => {
+ paragraph.normalize();
+
+ if (paragraph.childNodes.length === 1) {
+ const child = paragraph.childNodes[0];
+ if (child instanceof HTMLBRElement && child.dataset.ckeFiller !== "true") {
+ paragraphs.push(paragraph);
+ }
+ }
+ });
+
+ return paragraphs;
+}
+
+function reduceSpacerParagraphs(paragraphs: HTMLParagraphElement[]): void {
+ if (paragraphs.length === 0) {
+ return;
+ }
+
+ for (let i = 0, length = paragraphs.length; i < length; i++) {
+ const candidate = paragraphs[i];
+ let offset = 0;
+
+ // Searches for adjacent paragraphs.
+ while (i + offset + 1 < length) {
+ const nextCandidate = paragraphs[i + offset + 1];
+ if (candidate.nextElementSibling !== nextCandidate) {
+ break;
+ }
+
+ offset++;
+ }
+
+ if (offset === 0) {
+ // An offset of 0 means that this is a single paragraph and we
+ // can safely remove it.
+ candidate.remove();
+ } else {
+ // We need to reduce the number of paragraphs by half, unless it
+ // is an uneven number in which case we need to remove one
+ // additional paragraph.
+ const totalNumberOfParagraphs = offset + 1;
+ const numberOfParagraphsToRemove = Math.ceil(totalNumberOfParagraphs / 2);
+
+ const removeParagraphs = paragraphs.slice(i, i + numberOfParagraphsToRemove);
+ removeParagraphs.forEach((paragraph) => {
+ paragraph.remove();
+ });
+
+ i += offset;
+ }
+ }
+}
+
+export function normalizeLegacyMessage(element: HTMLElement): void {
+ if (!(element instanceof HTMLTextAreaElement)) {
+ throw new TypeError("Expected the element to be a <textarea>.");
+ }
+
+ const div = document.createElement("div");
+ div.innerHTML = element.value;
+
+ normalizeBr(div);
+ const paragraphs = getPossibleSpacerParagraphs(div);
+ reduceSpacerParagraphs(paragraphs);
+
+ element.value = div.innerHTML;
+}
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.0
*/
-define(["require", "exports", "tslib", "./Ckeditor/Attachment", "./Ckeditor/Media", "./Ckeditor/Mention", "./Ckeditor/Quote", "./Ckeditor/Autosave", "./Ckeditor/Configuration", "./Ckeditor/Event", "./Ckeditor/SubmitOnEnter", "./Ckeditor/Cleanup", "../Devtools", "ckeditor5-bundle"], function (require, exports, tslib_1, Attachment_1, Media_1, Mention_1, Quote_1, Autosave_1, Configuration_1, Event_1, SubmitOnEnter_1, Cleanup_1, Devtools_1) {
+define(["require", "exports", "tslib", "./Ckeditor/Attachment", "./Ckeditor/Media", "./Ckeditor/Mention", "./Ckeditor/Quote", "./Ckeditor/Autosave", "./Ckeditor/Configuration", "./Ckeditor/Event", "./Ckeditor/SubmitOnEnter", "./Ckeditor/Normalizer", "../Devtools", "ckeditor5-bundle"], function (require, exports, tslib_1, Attachment_1, Media_1, Mention_1, Quote_1, Autosave_1, Configuration_1, Event_1, SubmitOnEnter_1, Normalizer_1, Devtools_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCkeditorById = exports.getCkeditor = exports.setupCkeditor = void 0;
(0, Quote_1.setup)(element);
}
const configuration = initializeConfiguration(element, features, bbcodes);
- (0, Cleanup_1.normalizeLegacyMessage)(element);
+ (0, Normalizer_1.normalizeLegacyMessage)(element);
const cke = await window.CKEditor5.create(element, configuration);
const ckeditor = new Ckeditor(cke, features);
if (features.autosave) {
+++ /dev/null
-/**
- * Cleans up the markup of legacy messages.
- *
- * Messages created in the previous editor used empty paragraphs to create empty
- * lines. In addition, Firefox kept trailing <br> in lines with content, which
- * causes issues with CKEditor.
- *
- * @author Alexander Ebert
- * @copyright 2001-2023 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @since 6.0
- */
-define(["require", "exports", "tslib", "../../Dom/Util"], function (require, exports, tslib_1, Util_1) {
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.normalizeLegacyMessage = void 0;
- Util_1 = tslib_1.__importDefault(Util_1);
- function normalizeBr(div) {
- div.querySelectorAll("br").forEach((br) => {
- unwrapBr(br);
- removeTrailingBr(br);
- });
- }
- function unwrapBr(br) {
- for (;;) {
- if (br.previousSibling || br.nextSibling) {
- return;
- }
- const parent = br.parentElement;
- switch (parent.tagName) {
- case "B":
- case "DEL":
- case "EM":
- case "I":
- case "STRONG":
- case "SUB":
- case "SUP":
- case "SPAN":
- case "U":
- parent.insertAdjacentElement("afterend", br);
- parent.remove();
- break;
- default:
- return;
- }
- }
- }
- function removeTrailingBr(br) {
- if (br.dataset.ckeFiller === "true") {
- return;
- }
- const paragraphOrTableCell = br.closest("p, td");
- if (paragraphOrTableCell === null) {
- return;
- }
- if (!Util_1.default.isAtNodeEnd(br, paragraphOrTableCell)) {
- return;
- }
- if (paragraphOrTableCell.tagName === "TD" || paragraphOrTableCell.childNodes.length > 1) {
- br.remove();
- }
- }
- function getPossibleSpacerParagraphs(div) {
- const paragraphs = [];
- div.querySelectorAll("p").forEach((paragraph) => {
- paragraph.normalize();
- if (paragraph.childNodes.length === 1) {
- const child = paragraph.childNodes[0];
- if (child instanceof HTMLBRElement && child.dataset.ckeFiller !== "true") {
- paragraphs.push(paragraph);
- }
- }
- });
- return paragraphs;
- }
- function reduceSpacerParagraphs(paragraphs) {
- if (paragraphs.length === 0) {
- return;
- }
- for (let i = 0, length = paragraphs.length; i < length; i++) {
- const candidate = paragraphs[i];
- let offset = 0;
- // Searches for adjacent paragraphs.
- while (i + offset + 1 < length) {
- const nextCandidate = paragraphs[i + offset + 1];
- if (candidate.nextElementSibling !== nextCandidate) {
- break;
- }
- offset++;
- }
- if (offset === 0) {
- // An offset of 0 means that this is a single paragraph and we
- // can safely remove it.
- candidate.remove();
- }
- else {
- // We need to reduce the number of paragraphs by half, unless it
- // is an uneven number in which case we need to remove one
- // additional paragraph.
- const totalNumberOfParagraphs = offset + 1;
- const numberOfParagraphsToRemove = Math.ceil(totalNumberOfParagraphs / 2);
- const removeParagraphs = paragraphs.slice(i, i + numberOfParagraphsToRemove);
- removeParagraphs.forEach((paragraph) => {
- paragraph.remove();
- });
- i += offset;
- }
- }
- }
- function normalizeLegacyMessage(element) {
- if (!(element instanceof HTMLTextAreaElement)) {
- throw new TypeError("Expected the element to be a <textarea>.");
- }
- const div = document.createElement("div");
- div.innerHTML = element.value;
- normalizeBr(div);
- const paragraphs = getPossibleSpacerParagraphs(div);
- reduceSpacerParagraphs(paragraphs);
- element.value = div.innerHTML;
- }
- exports.normalizeLegacyMessage = normalizeLegacyMessage;
-});
--- /dev/null
+/**
+ * Cleans up the markup of legacy messages.
+ *
+ * Messages created in the previous editor used empty paragraphs to create empty
+ * lines. In addition, Firefox kept trailing <br> in lines with content, which
+ * causes issues with CKEditor.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2023 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @since 6.0
+ */
+define(["require", "exports", "tslib", "../../Dom/Util"], function (require, exports, tslib_1, Util_1) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.normalizeLegacyMessage = void 0;
+ Util_1 = tslib_1.__importDefault(Util_1);
+ function normalizeBr(div) {
+ div.querySelectorAll("br").forEach((br) => {
+ unwrapBr(br);
+ removeTrailingBr(br);
+ });
+ }
+ function unwrapBr(br) {
+ for (;;) {
+ if (br.previousSibling || br.nextSibling) {
+ return;
+ }
+ const parent = br.parentElement;
+ switch (parent.tagName) {
+ case "B":
+ case "DEL":
+ case "EM":
+ case "I":
+ case "STRONG":
+ case "SUB":
+ case "SUP":
+ case "SPAN":
+ case "U":
+ parent.insertAdjacentElement("afterend", br);
+ parent.remove();
+ break;
+ default:
+ return;
+ }
+ }
+ }
+ function removeTrailingBr(br) {
+ if (br.dataset.ckeFiller === "true") {
+ return;
+ }
+ const paragraphOrTableCell = br.closest("p, td");
+ if (paragraphOrTableCell === null) {
+ return;
+ }
+ if (!Util_1.default.isAtNodeEnd(br, paragraphOrTableCell)) {
+ return;
+ }
+ if (paragraphOrTableCell.tagName === "TD" || paragraphOrTableCell.childNodes.length > 1) {
+ br.remove();
+ }
+ }
+ function getPossibleSpacerParagraphs(div) {
+ const paragraphs = [];
+ div.querySelectorAll("p").forEach((paragraph) => {
+ paragraph.normalize();
+ if (paragraph.childNodes.length === 1) {
+ const child = paragraph.childNodes[0];
+ if (child instanceof HTMLBRElement && child.dataset.ckeFiller !== "true") {
+ paragraphs.push(paragraph);
+ }
+ }
+ });
+ return paragraphs;
+ }
+ function reduceSpacerParagraphs(paragraphs) {
+ if (paragraphs.length === 0) {
+ return;
+ }
+ for (let i = 0, length = paragraphs.length; i < length; i++) {
+ const candidate = paragraphs[i];
+ let offset = 0;
+ // Searches for adjacent paragraphs.
+ while (i + offset + 1 < length) {
+ const nextCandidate = paragraphs[i + offset + 1];
+ if (candidate.nextElementSibling !== nextCandidate) {
+ break;
+ }
+ offset++;
+ }
+ if (offset === 0) {
+ // An offset of 0 means that this is a single paragraph and we
+ // can safely remove it.
+ candidate.remove();
+ }
+ else {
+ // We need to reduce the number of paragraphs by half, unless it
+ // is an uneven number in which case we need to remove one
+ // additional paragraph.
+ const totalNumberOfParagraphs = offset + 1;
+ const numberOfParagraphsToRemove = Math.ceil(totalNumberOfParagraphs / 2);
+ const removeParagraphs = paragraphs.slice(i, i + numberOfParagraphsToRemove);
+ removeParagraphs.forEach((paragraph) => {
+ paragraph.remove();
+ });
+ i += offset;
+ }
+ }
+ }
+ function normalizeLegacyMessage(element) {
+ if (!(element instanceof HTMLTextAreaElement)) {
+ throw new TypeError("Expected the element to be a <textarea>.");
+ }
+ const div = document.createElement("div");
+ div.innerHTML = element.value;
+ normalizeBr(div);
+ const paragraphs = getPossibleSpacerParagraphs(div);
+ reduceSpacerParagraphs(paragraphs);
+ element.value = div.innerHTML;
+ }
+ exports.normalizeLegacyMessage = normalizeLegacyMessage;
+});