From 18161fb921f424ddda0b74ecd669852102a77968 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Wed, 4 Nov 2020 20:38:15 +0100 Subject: [PATCH] Convert `Ui/Redactor/Html` to TypeScript Heads up! The old JS file did include references to dialogs (if was a shameless copy of `Ui/Redactor/Code`), but that was never implemented. I have removed the reminders and stripped properties/methods that have never been in use. --- .../js/WoltLabSuite/Core/Ui/Redactor/Html.js | 129 ++++--------- .../ts/WoltLabSuite/Core/Ui/Redactor/Html.js | 169 ------------------ .../ts/WoltLabSuite/Core/Ui/Redactor/Html.ts | 94 ++++++++++ 3 files changed, 125 insertions(+), 267 deletions(-) delete mode 100644 wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Redactor/Html.js create mode 100644 wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Redactor/Html.ts diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Redactor/Html.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Redactor/Html.js index 5770528f6a..1676104376 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Redactor/Html.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Redactor/Html.js @@ -2,140 +2,73 @@ * Manages html code blocks. * * @author Alexander Ebert - * @copyright 2001-2019 WoltLab GmbH + * @copyright 2001-2019 WoltLab GmbH * @license GNU Lesser General Public License * @module WoltLabSuite/Core/Ui/Redactor/Html */ -define(['EventHandler', 'EventKey', 'Language', 'StringUtil', 'Dom/Util', 'Ui/Dialog', './PseudoHeader'], function (EventHandler, EventKey, Language, StringUtil, DomUtil, UiDialog, UiRedactorPseudoHeader) { +define(["require", "exports", "tslib", "../../Core", "../../Event/Handler", "../../Language"], function (require, exports, tslib_1, Core, EventHandler, Language) { "use strict"; - if (!COMPILER_TARGET_DEFAULT) { - var Fake = function () { }; - Fake.prototype = { - init: function () { }, - _bbcodeCode: function () { }, - _observeLoad: function () { }, - _edit: function () { }, - _save: function () { }, - _setTitle: function () { }, - _delete: function () { }, - _dialogSetup: function () { } - }; - return Fake; - } - var _headerHeight = 0; - /** - * @param {Object} editor editor instance - * @constructor - */ - function UiRedactorHtml(editor) { this.init(editor); } - UiRedactorHtml.prototype = { + Core = tslib_1.__importStar(Core); + EventHandler = tslib_1.__importStar(EventHandler); + Language = tslib_1.__importStar(Language); + class UiRedactorHtml { /** * Initializes the source code management. - * - * @param {Object} editor editor instance */ - init: function (editor) { + constructor(editor) { + this._pre = null; this._editor = editor; this._elementId = this._editor.$element[0].id; - this._pre = null; - EventHandler.add('com.woltlab.wcf.redactor2', 'bbcode_woltlabHtml_' + this._elementId, this._bbcodeCode.bind(this)); - EventHandler.add('com.woltlab.wcf.redactor2', 'observe_load_' + this._elementId, this._observeLoad.bind(this)); + EventHandler.add("com.woltlab.wcf.redactor2", `bbcode_woltlabHtml_${this._elementId}`, (data) => this._bbcodeCode(data)); + EventHandler.add("com.woltlab.wcf.redactor2", `observe_load_${this._elementId}`, () => this._observeLoad()); // support for active button marking - this._editor.opts.activeButtonsStates['woltlab-html'] = 'woltlabHtml'; - // static bind to ensure that removing works - this._callbackEdit = this._edit.bind(this); + this._editor.opts.activeButtonsStates["woltlab-html"] = "woltlabHtml"; // bind listeners on init this._observeLoad(); - }, + } /** * Intercepts the insertion of `[woltlabHtml]` tags and uses a native `
` instead.
-         *
-         * @param       {Object}        data    event data
-         * @protected
          */
-        _bbcodeCode: function (data) {
+        _bbcodeCode(data) {
             data.cancel = true;
-            var pre = this._editor.selection.block();
-            if (pre && pre.nodeName === 'PRE' && !pre.classList.contains('woltlabHtml')) {
+            let pre = this._editor.selection.block();
+            if (pre && pre.nodeName === "PRE" && !pre.classList.contains("woltlabHtml")) {
                 return;
             }
-            this._editor.button.toggle({}, 'pre', 'func', 'block.format');
+            this._editor.button.toggle({}, "pre", "func", "block.format");
             pre = this._editor.selection.block();
-            if (pre && pre.nodeName === 'PRE') {
-                pre.classList.add('woltlabHtml');
-                if (pre.childElementCount === 1 && pre.children[0].nodeName === 'BR') {
+            if (pre && pre.nodeName === "PRE") {
+                pre.classList.add("woltlabHtml");
+                if (pre.childElementCount === 1 && pre.children[0].nodeName === "BR") {
                     // drop superfluous linebreak
                     pre.removeChild(pre.children[0]);
                 }
                 this._setTitle(pre);
-                pre.addEventListener('click', this._callbackEdit);
                 // work-around for Safari
                 this._editor.caret.end(pre);
             }
-        },
+        }
         /**
          * Binds event listeners and sets quote title on both editor
          * initialization and when switching back from code view.
-         *
-         * @protected
          */
-        _observeLoad: function () {
-            elBySelAll('pre.woltlabHtml', this._editor.$editor[0], (function (pre) {
-                pre.addEventListener('mousedown', this._callbackEdit);
+        _observeLoad() {
+            this._editor.$editor[0].querySelectorAll("pre.woltlabHtml").forEach((pre) => {
                 this._setTitle(pre);
-            }).bind(this));
-        },
-        /**
-         * Opens the dialog overlay to edit the code's properties.
-         *
-         * @param       {Event}         event           event object
-         * @protected
-         */
-        _edit: function (event) {
-            var pre = event.currentTarget;
-            if (_headerHeight === 0) {
-                _headerHeight = UiRedactorPseudoHeader.getHeight(pre);
-            }
-            // check if the click hit the header
-            var offset = DomUtil.offset(pre);
-            if (event.pageY > offset.top && event.pageY < (offset.top + _headerHeight)) {
-                event.preventDefault();
-                this._editor.selection.save();
-                this._pre = pre;
-                console.warn("should edit");
-            }
-        },
+            });
+        }
         /**
          * Sets or updates the code's header title.
-         *
-         * @param       {Element}       pre     code element
-         * @protected
          */
-        _setTitle: function (pre) {
-            ['title', 'description'].forEach(function (title) {
-                var phrase = Language.get('wcf.editor.html.' + title);
-                if (elData(pre, title) !== phrase) {
-                    elData(pre, title, phrase);
+        _setTitle(pre) {
+            ["title", "description"].forEach((title) => {
+                const phrase = Language.get(`wcf.editor.html.${title}`);
+                if (pre.dataset[title] !== phrase) {
+                    pre.dataset[title] = phrase;
                 }
             });
-        },
-        _delete: function (event) {
-            console.warn("should delete");
-            event.preventDefault();
-            var caretEnd = this._pre.nextElementSibling || this._pre.previousElementSibling;
-            if (caretEnd === null && this._pre.parentNode !== this._editor.core.editor()[0]) {
-                caretEnd = this._pre.parentNode;
-            }
-            if (caretEnd === null) {
-                this._editor.code.set('');
-                this._editor.focus.end();
-            }
-            else {
-                elRemove(this._pre);
-                this._editor.caret.end(caretEnd);
-            }
-            UiDialog.close(this);
         }
-    };
+    }
+    Core.enableLegacyInheritance(UiRedactorHtml);
     return UiRedactorHtml;
 });
diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Redactor/Html.js b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Redactor/Html.js
deleted file mode 100644
index bca0009757..0000000000
--- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Redactor/Html.js
+++ /dev/null
@@ -1,169 +0,0 @@
-/**
- * Manages html code blocks.
- * 
- * @author      Alexander Ebert
- * @copyright	2001-2019 WoltLab GmbH
- * @license     GNU Lesser General Public License 
- * @module      WoltLabSuite/Core/Ui/Redactor/Html
- */
-define(['EventHandler', 'EventKey', 'Language', 'StringUtil', 'Dom/Util', 'Ui/Dialog', './PseudoHeader'], function (EventHandler, EventKey, Language, StringUtil, DomUtil, UiDialog, UiRedactorPseudoHeader) {
-	"use strict";
-	
-	if (!COMPILER_TARGET_DEFAULT) {
-		var Fake = function() {};
-		Fake.prototype = {
-			init: function() {},
-			_bbcodeCode: function() {},
-			_observeLoad: function() {},
-			_edit: function() {},
-			_save: function() {},
-			_setTitle: function() {},
-			_delete: function() {},
-			_dialogSetup: function() {}
-		};
-		return Fake;
-	}
-	
-	var _headerHeight = 0;
-	
-	/**
-	 * @param       {Object}        editor  editor instance
-	 * @constructor
-	 */
-	function UiRedactorHtml(editor) { this.init(editor); }
-	UiRedactorHtml.prototype = {
-		/**
-		 * Initializes the source code management.
-		 *
-		 * @param       {Object}        editor  editor instance
-		 */
-		init: function(editor) {
-			this._editor = editor;
-			this._elementId = this._editor.$element[0].id;
-			this._pre = null;
-			
-			EventHandler.add('com.woltlab.wcf.redactor2', 'bbcode_woltlabHtml_' + this._elementId, this._bbcodeCode.bind(this));
-			EventHandler.add('com.woltlab.wcf.redactor2', 'observe_load_' + this._elementId, this._observeLoad.bind(this));
-			
-			// support for active button marking
-			this._editor.opts.activeButtonsStates['woltlab-html'] = 'woltlabHtml';
-			
-			// static bind to ensure that removing works
-			this._callbackEdit = this._edit.bind(this);
-			
-			// bind listeners on init
-			this._observeLoad();
-		},
-		
-		/**
-		 * Intercepts the insertion of `[woltlabHtml]` tags and uses a native `
` instead.
-		 *
-		 * @param       {Object}        data    event data
-		 * @protected
-		 */
-		_bbcodeCode: function(data) {
-			data.cancel = true;
-			
-			var pre = this._editor.selection.block();
-			if (pre && pre.nodeName === 'PRE' && !pre.classList.contains('woltlabHtml')) {
-				return;
-			}
-			
-			this._editor.button.toggle({}, 'pre', 'func', 'block.format');
-			
-			pre = this._editor.selection.block();
-			if (pre && pre.nodeName === 'PRE') {
-				pre.classList.add('woltlabHtml');
-				
-				if (pre.childElementCount === 1 && pre.children[0].nodeName === 'BR') {
-					// drop superfluous linebreak
-					pre.removeChild(pre.children[0]);
-				}
-				
-				this._setTitle(pre);
-				
-				pre.addEventListener('click', this._callbackEdit);
-				
-				// work-around for Safari
-				this._editor.caret.end(pre);
-			}
-		},
-		
-		/**
-		 * Binds event listeners and sets quote title on both editor
-		 * initialization and when switching back from code view.
-		 *
-		 * @protected
-		 */
-		_observeLoad: function() {
-			elBySelAll('pre.woltlabHtml', this._editor.$editor[0], (function(pre) {
-				pre.addEventListener('mousedown', this._callbackEdit);
-				this._setTitle(pre);
-			}).bind(this));
-		},
-		
-		/**
-		 * Opens the dialog overlay to edit the code's properties.
-		 *
-		 * @param       {Event}         event           event object
-		 * @protected
-		 */
-		_edit: function(event) {
-			var pre = event.currentTarget;
-			
-			if (_headerHeight === 0) {
-				_headerHeight = UiRedactorPseudoHeader.getHeight(pre);
-			}
-			
-			// check if the click hit the header
-			var offset = DomUtil.offset(pre);
-			if (event.pageY > offset.top && event.pageY < (offset.top + _headerHeight)) {
-				event.preventDefault();
-				
-				this._editor.selection.save();
-				this._pre = pre;
-				
-				console.warn("should edit");
-			}
-		},
-		
-		/**
-		 * Sets or updates the code's header title.
-		 *
-		 * @param       {Element}       pre     code element
-		 * @protected
-		 */
-		_setTitle: function(pre) {
-			['title', 'description'].forEach(function(title) {
-				var phrase = Language.get('wcf.editor.html.' + title);
-				
-				if (elData(pre, title) !== phrase) {
-					elData(pre, title, phrase);
-				}
-			});
-		},
-		
-		_delete: function (event) {
-			console.warn("should delete");
-			event.preventDefault();
-			
-			var caretEnd = this._pre.nextElementSibling || this._pre.previousElementSibling;
-			if (caretEnd === null && this._pre.parentNode !== this._editor.core.editor()[0]) {
-				caretEnd = this._pre.parentNode;
-			}
-			
-			if (caretEnd === null) {
-				this._editor.code.set('');
-				this._editor.focus.end();
-			}
-			else {
-				elRemove(this._pre);
-				this._editor.caret.end(caretEnd);
-			}
-			
-			UiDialog.close(this);
-		}
-	};
-	
-	return UiRedactorHtml;
-});
diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Redactor/Html.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Redactor/Html.ts
new file mode 100644
index 0000000000..a31d89b2cb
--- /dev/null
+++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Redactor/Html.ts
@@ -0,0 +1,94 @@
+/**
+ * Manages html code blocks.
+ *
+ * @author      Alexander Ebert
+ * @copyright  2001-2019 WoltLab GmbH
+ * @license     GNU Lesser General Public License 
+ * @module      WoltLabSuite/Core/Ui/Redactor/Html
+ */
+
+import * as Core from "../../Core";
+import * as EventHandler from "../../Event/Handler";
+import * as Language from "../../Language";
+import { RedactorEditor } from "./Editor";
+
+class UiRedactorHtml {
+  protected readonly _editor: RedactorEditor;
+  protected readonly _elementId: string;
+  protected _pre: HTMLElement | null = null;
+
+  /**
+   * Initializes the source code management.
+   */
+  constructor(editor: RedactorEditor) {
+    this._editor = editor;
+    this._elementId = this._editor.$element[0].id;
+
+    EventHandler.add("com.woltlab.wcf.redactor2", `bbcode_woltlabHtml_${this._elementId}`, (data) =>
+      this._bbcodeCode(data),
+    );
+    EventHandler.add("com.woltlab.wcf.redactor2", `observe_load_${this._elementId}`, () => this._observeLoad());
+
+    // support for active button marking
+    this._editor.opts.activeButtonsStates["woltlab-html"] = "woltlabHtml";
+
+    // bind listeners on init
+    this._observeLoad();
+  }
+
+  /**
+   * Intercepts the insertion of `[woltlabHtml]` tags and uses a native `
` instead.
+   */
+  protected _bbcodeCode(data: { cancel: boolean }): void {
+    data.cancel = true;
+
+    let pre = this._editor.selection.block();
+    if (pre && pre.nodeName === "PRE" && !pre.classList.contains("woltlabHtml")) {
+      return;
+    }
+
+    this._editor.button.toggle({}, "pre", "func", "block.format");
+
+    pre = this._editor.selection.block();
+    if (pre && pre.nodeName === "PRE") {
+      pre.classList.add("woltlabHtml");
+
+      if (pre.childElementCount === 1 && pre.children[0].nodeName === "BR") {
+        // drop superfluous linebreak
+        pre.removeChild(pre.children[0]);
+      }
+
+      this._setTitle(pre);
+
+      // work-around for Safari
+      this._editor.caret.end(pre);
+    }
+  }
+
+  /**
+   * Binds event listeners and sets quote title on both editor
+   * initialization and when switching back from code view.
+   */
+  protected _observeLoad(): void {
+    this._editor.$editor[0].querySelectorAll("pre.woltlabHtml").forEach((pre: HTMLElement) => {
+      this._setTitle(pre);
+    });
+  }
+
+  /**
+   * Sets or updates the code's header title.
+   */
+  protected _setTitle(pre: HTMLElement): void {
+    ["title", "description"].forEach((title) => {
+      const phrase = Language.get(`wcf.editor.html.${title}`);
+
+      if (pre.dataset[title] !== phrase) {
+        pre.dataset[title] = phrase;
+      }
+    });
+  }
+}
+
+Core.enableLegacyInheritance(UiRedactorHtml);
+
+export = UiRedactorHtml;
-- 
2.20.1