* Manages spoilers.
*
* @author Alexander Ebert
- * @copyright 2001-2019 WoltLab GmbH
+ * @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @module WoltLabSuite/Core/Ui/Redactor/Spoiler
*/
-define(['EventHandler', 'EventKey', 'Language', 'StringUtil', 'Dom/Util', 'Ui/Dialog', './PseudoHeader'], function (EventHandler, EventKey, Language, StringUtil, DomUtil, UiDialog, UiRedactorPseudoHeader) {
+define(["require", "exports", "tslib", "../../Core", "../../Dom/Util", "../../Event/Handler", "../../Language", "../Dialog", "./PseudoHeader"], function (require, exports, tslib_1, Core, Util_1, EventHandler, Language, Dialog_1, UiRedactorPseudoHeader) {
"use strict";
- if (!COMPILER_TARGET_DEFAULT) {
- var Fake = function () { };
- Fake.prototype = {
- init: function () { },
- _bbcodeSpoiler: function () { },
- _observeLoad: function () { },
- _edit: function () { },
- _setTitle: function () { },
- _delete: function () { },
- _dialogSetup: function () { },
- _dialogSubmit: function () { }
- };
- return Fake;
- }
- var _headerHeight = 0;
- /**
- * @param {Object} editor editor instance
- * @constructor
- */
- function UiRedactorSpoiler(editor) { this.init(editor); }
- UiRedactorSpoiler.prototype = {
+ Core = tslib_1.__importStar(Core);
+ Util_1 = tslib_1.__importDefault(Util_1);
+ EventHandler = tslib_1.__importStar(EventHandler);
+ Language = tslib_1.__importStar(Language);
+ Dialog_1 = tslib_1.__importDefault(Dialog_1);
+ UiRedactorPseudoHeader = tslib_1.__importStar(UiRedactorPseudoHeader);
+ let _headerHeight = 0;
+ class UiRedactorSpoiler {
/**
* Initializes the spoiler management.
- *
- * @param {Object} editor editor instance
*/
- init: function (editor) {
+ constructor(editor) {
+ this._spoiler = null;
this._editor = editor;
this._elementId = this._editor.$element[0].id;
- this._spoiler = null;
- EventHandler.add('com.woltlab.wcf.redactor2', 'bbcode_spoiler_' + this._elementId, this._bbcodeSpoiler.bind(this));
- EventHandler.add('com.woltlab.wcf.redactor2', 'observe_load_' + this._elementId, this._observeLoad.bind(this));
- // static bind to ensure that removing works
- this._callbackEdit = this._edit.bind(this);
+ EventHandler.add("com.woltlab.wcf.redactor2", `bbcode_spoiler_${this._elementId}`, (data) => this._bbcodeSpoiler(data));
+ EventHandler.add("com.woltlab.wcf.redactor2", `observe_load_${this._elementId}`, () => this._observeLoad());
// bind listeners on init
this._observeLoad();
- },
+ }
/**
* Intercepts the insertion of `[spoiler]` tags and uses
* the custom `<woltlab-spoiler>` element instead.
- *
- * @param {Object} data event data
- * @protected
*/
- _bbcodeSpoiler: function (data) {
+ _bbcodeSpoiler(data) {
data.cancel = true;
- this._editor.button.toggle({}, 'woltlab-spoiler', 'func', 'block.format');
- var spoiler = this._editor.selection.block();
+ this._editor.button.toggle({}, "woltlab-spoiler", "func", "block.format");
+ let spoiler = this._editor.selection.block();
if (spoiler) {
// iOS Safari might set the caret inside the spoiler.
- if (spoiler.nodeName === 'P') {
- spoiler = spoiler.parentNode;
+ if (spoiler.nodeName === "P") {
+ spoiler = spoiler.parentElement;
}
- if (spoiler.nodeName === 'WOLTLAB-SPOILER') {
+ if (spoiler.nodeName === "WOLTLAB-SPOILER") {
this._setTitle(spoiler);
- spoiler.addEventListener('click', this._callbackEdit);
+ spoiler.addEventListener("click", (ev) => this._edit(ev));
// work-around for Safari
this._editor.caret.end(spoiler);
}
}
- },
+ }
/**
* Binds event listeners and sets quote title on both editor
* initialization and when switching back from code view.
- *
- * @protected
*/
- _observeLoad: function () {
- elBySelAll('woltlab-spoiler', this._editor.$editor[0], (function (spoiler) {
- spoiler.addEventListener('mousedown', this._callbackEdit);
+ _observeLoad() {
+ this._editor.$editor[0].querySelectorAll("woltlab-spoiler").forEach((spoiler) => {
+ spoiler.addEventListener("mousedown", (ev) => this._edit(ev));
this._setTitle(spoiler);
- }).bind(this));
- },
+ });
+ }
/**
* Opens the dialog overlay to edit the spoiler's properties.
- *
- * @param {Event} event event object
- * @protected
*/
- _edit: function (event) {
- var spoiler = event.currentTarget;
+ _edit(event) {
+ const spoiler = event.currentTarget;
if (_headerHeight === 0) {
_headerHeight = UiRedactorPseudoHeader.getHeight(spoiler);
}
// check if the click hit the header
- var offset = DomUtil.offset(spoiler);
- if (event.pageY > offset.top && event.pageY < (offset.top + _headerHeight)) {
+ const offset = Util_1.default.offset(spoiler);
+ if (event.pageY > offset.top && event.pageY < offset.top + _headerHeight) {
event.preventDefault();
this._editor.selection.save();
this._spoiler = spoiler;
- UiDialog.open(this);
+ Dialog_1.default.open(this);
}
- },
+ }
/**
* Saves the changes to the spoiler's properties.
*
* @protected
*/
- _dialogSubmit: function () {
- elData(this._spoiler, 'label', elById('redactor-spoiler-' + this._elementId + '-label').value);
- this._setTitle(this._spoiler);
- this._editor.caret.after(this._spoiler);
- UiDialog.close(this);
- },
+ _dialogSubmit() {
+ const spoiler = this._spoiler;
+ const label = document.getElementById("redactor-spoiler-" + this._elementId + "-label");
+ spoiler.dataset.label = label.value;
+ this._setTitle(spoiler);
+ this._editor.caret.after(spoiler);
+ Dialog_1.default.close(this);
+ }
/**
* Sets or updates the spoiler's header title.
- *
- * @param {Element} spoiler spoiler element
- * @protected
*/
- _setTitle: function (spoiler) {
- var title = Language.get('wcf.editor.spoiler.title', { label: elData(spoiler, 'label') });
- if (elData(spoiler, 'title') !== title) {
- elData(spoiler, 'title', title);
+ _setTitle(spoiler) {
+ const title = Language.get("wcf.editor.spoiler.title", { label: spoiler.dataset.label || "" });
+ if (spoiler.dataset.title !== title) {
+ spoiler.dataset.title = title;
}
- },
- _delete: function (event) {
+ }
+ _delete(event) {
event.preventDefault();
- var caretEnd = this._spoiler.nextElementSibling || this._spoiler.previousElementSibling;
- if (caretEnd === null && this._spoiler.parentNode !== this._editor.core.editor()[0]) {
- caretEnd = this._spoiler.parentNode;
+ const spoiler = this._spoiler;
+ let caretEnd = spoiler.nextElementSibling || spoiler.previousElementSibling;
+ if (caretEnd === null && spoiler.parentElement !== this._editor.core.editor()[0]) {
+ caretEnd = spoiler.parentElement;
}
if (caretEnd === null) {
- this._editor.code.set('');
+ this._editor.code.set("");
this._editor.focus.end();
}
else {
- elRemove(this._spoiler);
+ spoiler.remove();
this._editor.caret.end(caretEnd);
}
- UiDialog.close(this);
- },
- _dialogSetup: function () {
- var id = 'redactor-spoiler-' + this._elementId, idButtonDelete = id + '-button-delete', idButtonSave = id + '-button-save', idLabel = id + '-label';
+ Dialog_1.default.close(this);
+ }
+ _dialogSetup() {
+ const id = `redactor-spoiler-${this._elementId}`;
+ const idButtonDelete = `${id}-button-delete`;
+ const idButtonSave = `${id}-button-save`;
+ const idLabel = `${id}-label`;
return {
id: id,
options: {
- onClose: (function () {
+ onClose: () => {
this._editor.selection.restore();
- UiDialog.destroy(this);
- }).bind(this),
- onSetup: (function () {
- elById(idButtonDelete).addEventListener('click', this._delete.bind(this));
- }).bind(this),
- onShow: (function () {
- elById(idLabel).value = elData(this._spoiler, 'label');
- }).bind(this),
- title: Language.get('wcf.editor.spoiler.edit')
+ Dialog_1.default.destroy(this);
+ },
+ onSetup: () => {
+ const button = document.getElementById(idButtonDelete);
+ button.addEventListener("click", (ev) => this._delete(ev));
+ },
+ onShow: () => {
+ const label = document.getElementById(idLabel);
+ label.value = this._spoiler.dataset.label || "";
+ },
+ title: Language.get("wcf.editor.spoiler.edit"),
},
- source: '<div class="section">'
- + '<dl>'
- + '<dt><label for="' + idLabel + '">' + Language.get('wcf.editor.spoiler.label') + '</label></dt>'
- + '<dd>'
- + '<input type="text" id="' + idLabel + '" class="long" data-dialog-submit-on-enter="true">'
- + '<small>' + Language.get('wcf.editor.spoiler.label.description') + '</small>'
- + '</dd>'
- + '</dl>'
- + '</div>'
- + '<div class="formSubmit">'
- + '<button id="' + idButtonSave + '" class="buttonPrimary" data-type="submit">' + Language.get('wcf.global.button.save') + '</button>'
- + '<button id="' + idButtonDelete + '">' + Language.get('wcf.global.button.delete') + '</button>'
- + '</div>'
+ source: `<div class="section">
+ <dl>
+ <dt>
+ <label for="${idLabel}">${Language.get("wcf.editor.spoiler.label")}</label>
+ </dt>
+ <dd>
+ <input type="text" id="${idLabel}" class="long" data-dialog-submit-on-enter="true">
+ <small>${Language.get("wcf.editor.spoiler.label.description")}</small>
+ </dd>
+ </dl>
+ </div>
+ <div class="formSubmit">
+ <button id="${idButtonSave}" class="buttonPrimary" data-type="submit">${Language.get("wcf.global.button.save")}</button>
+ <button id="${idButtonDelete}">${Language.get("wcf.global.button.delete")}</button>
+ </div>`,
};
}
- };
+ }
+ Core.enableLegacyInheritance(UiRedactorSpoiler);
return UiRedactorSpoiler;
});
import * as StringUtil from "../../StringUtil";
import UiDialog from "../Dialog";
import { DialogCallbackObject, DialogCallbackSetup } from "../Dialog/Data";
-import { RedactorEditor } from "./Editor";
+import { RedactorEditor, WoltLabEventData } from "./Editor";
import * as UiRedactorPseudoHeader from "./PseudoHeader";
import PrismMeta from "../../prism-meta";
/**
* Intercepts the insertion of `[code]` tags and uses a native `<pre>` instead.
*/
- protected _bbcodeCode(data: { cancel: boolean }): void {
+ protected _bbcodeCode(data: WoltLabEventData): void {
data.cancel = true;
let pre = this._editor.selection.block();
+++ /dev/null
-/**
- * Manages spoilers.
- *
- * @author Alexander Ebert
- * @copyright 2001-2019 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLabSuite/Core/Ui/Redactor/Spoiler
- */
-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() {},
- _bbcodeSpoiler: function() {},
- _observeLoad: function() {},
- _edit: function() {},
- _setTitle: function() {},
- _delete: function() {},
- _dialogSetup: function() {},
- _dialogSubmit: function() {}
- };
- return Fake;
- }
-
- var _headerHeight = 0;
-
- /**
- * @param {Object} editor editor instance
- * @constructor
- */
- function UiRedactorSpoiler(editor) { this.init(editor); }
- UiRedactorSpoiler.prototype = {
- /**
- * Initializes the spoiler management.
- *
- * @param {Object} editor editor instance
- */
- init: function(editor) {
- this._editor = editor;
- this._elementId = this._editor.$element[0].id;
- this._spoiler = null;
-
- EventHandler.add('com.woltlab.wcf.redactor2', 'bbcode_spoiler_' + this._elementId, this._bbcodeSpoiler.bind(this));
- EventHandler.add('com.woltlab.wcf.redactor2', 'observe_load_' + this._elementId, this._observeLoad.bind(this));
-
- // static bind to ensure that removing works
- this._callbackEdit = this._edit.bind(this);
-
- // bind listeners on init
- this._observeLoad();
- },
-
- /**
- * Intercepts the insertion of `[spoiler]` tags and uses
- * the custom `<woltlab-spoiler>` element instead.
- *
- * @param {Object} data event data
- * @protected
- */
- _bbcodeSpoiler: function(data) {
- data.cancel = true;
-
- this._editor.button.toggle({}, 'woltlab-spoiler', 'func', 'block.format');
-
- var spoiler = this._editor.selection.block();
- if (spoiler) {
- // iOS Safari might set the caret inside the spoiler.
- if (spoiler.nodeName === 'P') {
- spoiler = spoiler.parentNode;
- }
-
- if (spoiler.nodeName === 'WOLTLAB-SPOILER') {
- this._setTitle(spoiler);
-
- spoiler.addEventListener('click', this._callbackEdit);
-
- // work-around for Safari
- this._editor.caret.end(spoiler);
- }
- }
- },
-
- /**
- * Binds event listeners and sets quote title on both editor
- * initialization and when switching back from code view.
- *
- * @protected
- */
- _observeLoad: function() {
- elBySelAll('woltlab-spoiler', this._editor.$editor[0], (function(spoiler) {
- spoiler.addEventListener('mousedown', this._callbackEdit);
- this._setTitle(spoiler);
- }).bind(this));
- },
-
- /**
- * Opens the dialog overlay to edit the spoiler's properties.
- *
- * @param {Event} event event object
- * @protected
- */
- _edit: function(event) {
- var spoiler = event.currentTarget;
-
- if (_headerHeight === 0) {
- _headerHeight = UiRedactorPseudoHeader.getHeight(spoiler);
- }
-
- // check if the click hit the header
- var offset = DomUtil.offset(spoiler);
- if (event.pageY > offset.top && event.pageY < (offset.top + _headerHeight)) {
- event.preventDefault();
-
- this._editor.selection.save();
- this._spoiler = spoiler;
-
- UiDialog.open(this);
- }
- },
-
- /**
- * Saves the changes to the spoiler's properties.
- *
- * @protected
- */
- _dialogSubmit: function() {
- elData(this._spoiler, 'label', elById('redactor-spoiler-' + this._elementId + '-label').value);
-
- this._setTitle(this._spoiler);
- this._editor.caret.after(this._spoiler);
-
- UiDialog.close(this);
- },
-
- /**
- * Sets or updates the spoiler's header title.
- *
- * @param {Element} spoiler spoiler element
- * @protected
- */
- _setTitle: function(spoiler) {
- var title = Language.get('wcf.editor.spoiler.title', { label: elData(spoiler, 'label') });
-
- if (elData(spoiler, 'title') !== title) {
- elData(spoiler, 'title', title);
- }
- },
-
- _delete: function (event) {
- event.preventDefault();
-
- var caretEnd = this._spoiler.nextElementSibling || this._spoiler.previousElementSibling;
- if (caretEnd === null && this._spoiler.parentNode !== this._editor.core.editor()[0]) {
- caretEnd = this._spoiler.parentNode;
- }
-
- if (caretEnd === null) {
- this._editor.code.set('');
- this._editor.focus.end();
- }
- else {
- elRemove(this._spoiler);
- this._editor.caret.end(caretEnd);
- }
-
- UiDialog.close(this);
- },
-
- _dialogSetup: function() {
- var id = 'redactor-spoiler-' + this._elementId,
- idButtonDelete = id + '-button-delete',
- idButtonSave = id + '-button-save',
- idLabel = id + '-label';
-
- return {
- id: id,
- options: {
- onClose: (function () {
- this._editor.selection.restore();
-
- UiDialog.destroy(this);
- }).bind(this),
-
- onSetup: (function() {
- elById(idButtonDelete).addEventListener('click', this._delete.bind(this));
- }).bind(this),
-
- onShow: (function() {
- elById(idLabel).value = elData(this._spoiler, 'label');
- }).bind(this),
-
- title: Language.get('wcf.editor.spoiler.edit')
- },
- source: '<div class="section">'
- + '<dl>'
- + '<dt><label for="' + idLabel + '">' + Language.get('wcf.editor.spoiler.label') + '</label></dt>'
- + '<dd>'
- + '<input type="text" id="' + idLabel + '" class="long" data-dialog-submit-on-enter="true">'
- + '<small>' + Language.get('wcf.editor.spoiler.label.description') + '</small>'
- + '</dd>'
- + '</dl>'
- + '</div>'
- + '<div class="formSubmit">'
- + '<button id="' + idButtonSave + '" class="buttonPrimary" data-type="submit">' + Language.get('wcf.global.button.save') + '</button>'
- + '<button id="' + idButtonDelete + '">' + Language.get('wcf.global.button.delete') + '</button>'
- + '</div>'
- };
- }
- };
-
- return UiRedactorSpoiler;
-});
--- /dev/null
+/**
+ * Manages spoilers.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2019 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLabSuite/Core/Ui/Redactor/Spoiler
+ */
+
+import * as Core from "../../Core";
+import { DialogCallbackObject, DialogCallbackSetup } from "../Dialog/Data";
+import DomUtil from "../../Dom/Util";
+import * as EventHandler from "../../Event/Handler";
+import * as Language from "../../Language";
+import UiDialog from "../Dialog";
+import { RedactorEditor, WoltLabEventData } from "./Editor";
+import * as UiRedactorPseudoHeader from "./PseudoHeader";
+
+let _headerHeight = 0;
+
+class UiRedactorSpoiler implements DialogCallbackObject {
+ protected readonly _editor: RedactorEditor;
+ protected readonly _elementId: string;
+ protected _spoiler: HTMLElement | null = null;
+
+ /**
+ * Initializes the spoiler management.
+ */
+ constructor(editor: RedactorEditor) {
+ this._editor = editor;
+ this._elementId = this._editor.$element[0].id;
+
+ EventHandler.add("com.woltlab.wcf.redactor2", `bbcode_spoiler_${this._elementId}`, (data) =>
+ this._bbcodeSpoiler(data),
+ );
+ EventHandler.add("com.woltlab.wcf.redactor2", `observe_load_${this._elementId}`, () => this._observeLoad());
+
+ // bind listeners on init
+ this._observeLoad();
+ }
+
+ /**
+ * Intercepts the insertion of `[spoiler]` tags and uses
+ * the custom `<woltlab-spoiler>` element instead.
+ */
+ protected _bbcodeSpoiler(data: WoltLabEventData): void {
+ data.cancel = true;
+
+ this._editor.button.toggle({}, "woltlab-spoiler", "func", "block.format");
+
+ let spoiler = this._editor.selection.block();
+ if (spoiler) {
+ // iOS Safari might set the caret inside the spoiler.
+ if (spoiler.nodeName === "P") {
+ spoiler = spoiler.parentElement!;
+ }
+
+ if (spoiler.nodeName === "WOLTLAB-SPOILER") {
+ this._setTitle(spoiler);
+
+ spoiler.addEventListener("click", (ev) => this._edit(ev));
+
+ // work-around for Safari
+ this._editor.caret.end(spoiler);
+ }
+ }
+ }
+
+ /**
+ * 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("woltlab-spoiler").forEach((spoiler: HTMLElement) => {
+ spoiler.addEventListener("mousedown", (ev) => this._edit(ev));
+ this._setTitle(spoiler);
+ });
+ }
+
+ /**
+ * Opens the dialog overlay to edit the spoiler's properties.
+ */
+ protected _edit(event: MouseEvent): void {
+ const spoiler = event.currentTarget as HTMLElement;
+
+ if (_headerHeight === 0) {
+ _headerHeight = UiRedactorPseudoHeader.getHeight(spoiler);
+ }
+
+ // check if the click hit the header
+ const offset = DomUtil.offset(spoiler);
+ if (event.pageY > offset.top && event.pageY < offset.top + _headerHeight) {
+ event.preventDefault();
+
+ this._editor.selection.save();
+ this._spoiler = spoiler;
+
+ UiDialog.open(this);
+ }
+ }
+
+ /**
+ * Saves the changes to the spoiler's properties.
+ *
+ * @protected
+ */
+ _dialogSubmit(): void {
+ const spoiler = this._spoiler!;
+
+ const label = document.getElementById("redactor-spoiler-" + this._elementId + "-label") as HTMLInputElement;
+ spoiler.dataset.label = label.value;
+
+ this._setTitle(spoiler);
+ this._editor.caret.after(spoiler);
+
+ UiDialog.close(this);
+ }
+
+ /**
+ * Sets or updates the spoiler's header title.
+ */
+ protected _setTitle(spoiler: HTMLElement): void {
+ const title = Language.get("wcf.editor.spoiler.title", { label: spoiler.dataset.label || "" });
+
+ if (spoiler.dataset.title !== title) {
+ spoiler.dataset.title = title;
+ }
+ }
+
+ protected _delete(event: MouseEvent): void {
+ event.preventDefault();
+
+ const spoiler = this._spoiler!;
+
+ let caretEnd = spoiler.nextElementSibling || spoiler.previousElementSibling;
+ if (caretEnd === null && spoiler.parentElement !== this._editor.core.editor()[0]) {
+ caretEnd = spoiler.parentElement;
+ }
+
+ if (caretEnd === null) {
+ this._editor.code.set("");
+ this._editor.focus.end();
+ } else {
+ spoiler.remove();
+ this._editor.caret.end(caretEnd);
+ }
+
+ UiDialog.close(this);
+ }
+
+ _dialogSetup(): ReturnType<DialogCallbackSetup> {
+ const id = `redactor-spoiler-${this._elementId}`;
+ const idButtonDelete = `${id}-button-delete`;
+ const idButtonSave = `${id}-button-save`;
+ const idLabel = `${id}-label`;
+
+ return {
+ id: id,
+ options: {
+ onClose: () => {
+ this._editor.selection.restore();
+
+ UiDialog.destroy(this);
+ },
+
+ onSetup: () => {
+ const button = document.getElementById(idButtonDelete) as HTMLButtonElement;
+ button.addEventListener("click", (ev) => this._delete(ev));
+ },
+
+ onShow: () => {
+ const label = document.getElementById(idLabel) as HTMLInputElement;
+ label.value = this._spoiler!.dataset.label || "";
+ },
+
+ title: Language.get("wcf.editor.spoiler.edit"),
+ },
+ source: `<div class="section">
+ <dl>
+ <dt>
+ <label for="${idLabel}">${Language.get("wcf.editor.spoiler.label")}</label>
+ </dt>
+ <dd>
+ <input type="text" id="${idLabel}" class="long" data-dialog-submit-on-enter="true">
+ <small>${Language.get("wcf.editor.spoiler.label.description")}</small>
+ </dd>
+ </dl>
+ </div>
+ <div class="formSubmit">
+ <button id="${idButtonSave}" class="buttonPrimary" data-type="submit">${Language.get(
+ "wcf.global.button.save",
+ )}</button>
+ <button id="${idButtonDelete}">${Language.get("wcf.global.button.delete")}</button>
+ </div>`,
+ };
+ }
+}
+
+Core.enableLegacyInheritance(UiRedactorSpoiler);
+
+export = UiRedactorSpoiler;