* @module WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract
* @since 5.2
*/
-define(["require", "exports", "tslib", "./Manager", "../../../../Core"], function (require, exports, tslib_1, Manager_1, Core) {
+define(["require", "exports", "tslib", "./Manager", "../../../../Core"], function (require, exports, tslib_1, DependencyManager, Core) {
"use strict";
- Manager_1 = tslib_1.__importDefault(Manager_1);
+ DependencyManager = tslib_1.__importStar(DependencyManager);
Core = tslib_1.__importStar(Core);
class FormBuilderFormFieldDependency {
constructor(dependentElementId, fieldId) {
this._fields.push(this._noField);
}
}
- Manager_1.default.addDependency(this);
+ DependencyManager.addDependency(this);
}
}
Core.enableLegacyInheritance(FormBuilderFormFieldDependency);
* @module WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Abstract
* @since 5.2
*/
-define(["require", "exports", "tslib", "../Manager", "../../../../../Core"], function (require, exports, tslib_1, Manager_1, Core) {
+define(["require", "exports", "tslib", "../Manager", "../../../../../Core"], function (require, exports, tslib_1, DependencyManager, Core) {
"use strict";
- Manager_1 = tslib_1.__importDefault(Manager_1);
+ DependencyManager = tslib_1.__importStar(DependencyManager);
Core = tslib_1.__importStar(Core);
class Abstract {
constructor(containerId) {
if (this._container === null) {
throw new Error("Unknown container with id '" + containerId + "'.");
}
- Manager_1.default.addContainerCheckCallback(() => this.checkContainer());
+ DependencyManager.addContainerCheckCallback(() => this.checkContainer());
}
}
Core.enableLegacyInheritance(Abstract);
* @see module:WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract
* @since 5.2
*/
-define(["require", "exports", "tslib", "./Abstract", "../../../../../Core", "../Manager"], function (require, exports, tslib_1, Abstract_1, Core, Manager_1) {
+define(["require", "exports", "tslib", "./Abstract", "../../../../../Core", "../Manager"], function (require, exports, tslib_1, Abstract_1, Core, DependencyManager) {
"use strict";
Abstract_1 = tslib_1.__importDefault(Abstract_1);
Core = tslib_1.__importStar(Core);
- Manager_1 = tslib_1.__importDefault(Manager_1);
+ DependencyManager = tslib_1.__importStar(DependencyManager);
class Default extends Abstract_1.default {
checkContainer() {
if (Core.stringToBool(this._container.dataset.ignoreDependencies || "")) {
return;
}
// only consider containers that have not been hidden by their own dependencies
- if (Manager_1.default.isHiddenByDependencies(this._container)) {
+ if (DependencyManager.isHiddenByDependencies(this._container)) {
return;
}
const containerIsVisible = this._container.style.display !== "none";
}
// check containers again to make sure parent containers can react to
// changing the visibility of this container
- Manager_1.default.checkContainers();
+ DependencyManager.checkContainers();
}
}
}
* @see module:WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract
* @since 5.2
*/
-define(["require", "exports", "tslib", "./Abstract", "../Manager", "../../../../../Dom/Util", "../../../../../Ui/TabMenu", "../../../../../Core"], function (require, exports, tslib_1, Abstract_1, Manager_1, DomUtil, UiTabMenu, Core) {
+define(["require", "exports", "tslib", "./Abstract", "../Manager", "../../../../../Dom/Util", "../../../../../Ui/TabMenu", "../../../../../Core"], function (require, exports, tslib_1, Abstract_1, DependencyManager, DomUtil, UiTabMenu, Core) {
"use strict";
Abstract_1 = tslib_1.__importDefault(Abstract_1);
- Manager_1 = tslib_1.__importDefault(Manager_1);
+ DependencyManager = tslib_1.__importStar(DependencyManager);
DomUtil = tslib_1.__importStar(DomUtil);
UiTabMenu = tslib_1.__importStar(UiTabMenu);
Core = tslib_1.__importStar(Core);
class Tab extends Abstract_1.default {
checkContainer() {
// only consider containers that have not been hidden by their own dependencies
- if (Manager_1.default.isHiddenByDependencies(this._container)) {
+ if (DependencyManager.isHiddenByDependencies(this._container)) {
return;
}
const containerIsVisible = this._container.style.display !== "none";
}
// Check containers again to make sure parent containers can react to changing the visibility
// of this container.
- Manager_1.default.checkContainers();
+ DependencyManager.checkContainers();
}
}
}
* @see module:WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract
* @since 5.2
*/
-define(["require", "exports", "tslib", "./Abstract", "../Manager", "../../../../../Dom/Util", "../../../../../Ui/TabMenu", "../../../../../Core"], function (require, exports, tslib_1, Abstract_1, Manager_1, DomUtil, UiTabMenu, Core) {
+define(["require", "exports", "tslib", "./Abstract", "../Manager", "../../../../../Dom/Util", "../../../../../Ui/TabMenu", "../../../../../Core"], function (require, exports, tslib_1, Abstract_1, DependencyManager, DomUtil, UiTabMenu, Core) {
"use strict";
Abstract_1 = tslib_1.__importDefault(Abstract_1);
- Manager_1 = tslib_1.__importDefault(Manager_1);
+ DependencyManager = tslib_1.__importStar(DependencyManager);
DomUtil = tslib_1.__importStar(DomUtil);
UiTabMenu = tslib_1.__importStar(UiTabMenu);
Core = tslib_1.__importStar(Core);
class TabMenu extends Abstract_1.default {
checkContainer() {
// only consider containers that have not been hidden by their own dependencies
- if (Manager_1.default.isHiddenByDependencies(this._container)) {
+ if (DependencyManager.isHiddenByDependencies(this._container)) {
return;
}
const containerIsVisible = this._container.style.display !== "none";
}
// check containers again to make sure parent containers can react to
// changing the visibility of this container
- Manager_1.default.checkContainers();
+ DependencyManager.checkContainers();
}
}
}
* @see module:WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract
* @since 5.4
*/
-define(["require", "exports", "tslib", "./Abstract", "./Manager", "../../../../Core"], function (require, exports, tslib_1, Abstract_1, Manager_1, Core) {
+define(["require", "exports", "tslib", "./Abstract", "./Manager"], function (require, exports, tslib_1, Abstract_1, DependencyManager) {
"use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.IsNotClicked = void 0;
Abstract_1 = tslib_1.__importDefault(Abstract_1);
- Manager_1 = tslib_1.__importDefault(Manager_1);
- Core = tslib_1.__importStar(Core);
+ DependencyManager = tslib_1.__importStar(DependencyManager);
class IsNotClicked extends Abstract_1.default {
constructor(dependentElementId, fieldId) {
super(dependentElementId, fieldId);
// events.
this._field.addEventListener("click", () => {
this._field.dataset.isClicked = "1";
- Manager_1.default.checkDependencies();
+ DependencyManager.checkDependencies();
});
}
checkDependency() {
return this._field.dataset.isClicked !== "1";
}
}
- Core.enableLegacyInheritance(IsNotClicked);
- return IsNotClicked;
+ exports.IsNotClicked = IsNotClicked;
+ exports.default = IsNotClicked;
});
* @module WoltLabSuite/Core/Form/Builder/Field/Dependency/Manager
* @since 5.2
*/
-define(["require", "exports", "tslib", "../../../../Dom/Util", "../../../../Event/Handler", "../../../../Core"], function (require, exports, tslib_1, Util_1, EventHandler, Core) {
+define(["require", "exports", "tslib", "../../../../Dom/Util", "../../../../Event/Handler"], function (require, exports, tslib_1, Util_1, EventHandler) {
"use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.unregister = exports.register = exports.isHiddenByDependencies = exports.checkDependencies = exports.checkContainers = exports.addDependency = exports.addContainerCheckCallback = void 0;
Util_1 = tslib_1.__importDefault(Util_1);
EventHandler = tslib_1.__importStar(EventHandler);
- Core = tslib_1.__importStar(Core);
const _dependencyHiddenNodes = new Set();
const _fields = new Map();
- const _forms = new Set();
+ const _forms = new WeakSet();
const _nodeDependencies = new Map();
const _validatedFieldProperties = new WeakMap();
let _checkingContainers = false;
let _checkContainersAgain = true;
- const Manager = {
- /**
- * Hides the given node because of its own dependencies.
- */
- _hide(node) {
- node.style.display = "none";
- _dependencyHiddenNodes.add(node);
- // also hide tab menu entry
- if (node.classList.contains("tabMenuContent")) {
- node
- .parentNode.querySelector(".tabMenu")
- .querySelectorAll("li")
- .forEach((tabLink) => {
- if (tabLink.dataset.name === node.dataset.name) {
- tabLink.style.display = "none";
- }
- });
- }
- node.querySelectorAll("[max], [maxlength], [min], [required]").forEach((validatedField) => {
- const properties = new Map();
- const max = validatedField.getAttribute("max");
- if (max) {
- properties.set("max", max);
- validatedField.removeAttribute("max");
- }
- const maxlength = validatedField.getAttribute("maxlength");
- if (maxlength) {
- properties.set("maxlength", maxlength);
- validatedField.removeAttribute("maxlength");
+ /**
+ * Hides the given node because of its own dependencies.
+ */
+ function _hide(node) {
+ node.style.display = "none";
+ _dependencyHiddenNodes.add(node);
+ // also hide tab menu entry
+ if (node.classList.contains("tabMenuContent")) {
+ node
+ .parentNode.querySelector(".tabMenu")
+ .querySelectorAll("li")
+ .forEach((tabLink) => {
+ if (tabLink.dataset.name === node.dataset.name) {
+ tabLink.style.display = "none";
}
- const min = validatedField.getAttribute("min");
- if (min) {
- properties.set("min", min);
- validatedField.removeAttribute("min");
- }
- if (validatedField.required) {
- properties.set("required", "true");
- validatedField.removeAttribute("required");
- }
- _validatedFieldProperties.set(validatedField, properties);
});
- },
- /**
- * Shows the given node because of its own dependencies.
- */
- _show(node) {
- node.style.display = "block";
- _dependencyHiddenNodes.delete(node);
- // also show tab menu entry
- if (node.classList.contains("tabMenuContent")) {
- node
- .parentNode.querySelector(".tabMenu")
- .querySelectorAll("li")
- .forEach((tabLink) => {
- if (tabLink.dataset.name === node.dataset.name) {
- tabLink.style.display = "block";
- }
- });
+ }
+ node.querySelectorAll("[max], [maxlength], [min], [required]").forEach((validatedField) => {
+ const properties = new Map();
+ const max = validatedField.getAttribute("max");
+ if (max) {
+ properties.set("max", max);
+ validatedField.removeAttribute("max");
}
- node.querySelectorAll("input, select").forEach((validatedField) => {
- // if a container is shown, ignore all fields that
- // have a hidden parent element within the container
- let parentNode = validatedField.parentNode;
- while (parentNode !== node && parentNode.style.getPropertyValue("display") !== "none") {
- parentNode = parentNode.parentNode;
- }
- if (parentNode === node && _validatedFieldProperties.has(validatedField)) {
- const properties = _validatedFieldProperties.get(validatedField);
- if (properties.has("max")) {
- validatedField.setAttribute("max", properties.get("max"));
- }
- if (properties.has("maxlength")) {
- validatedField.setAttribute("maxlength", properties.get("maxlength"));
- }
- if (properties.has("min")) {
- validatedField.setAttribute("min", properties.get("min"));
- }
- if (properties.has("required")) {
- validatedField.setAttribute("required", "");
- }
- _validatedFieldProperties.delete(validatedField);
- }
- });
- },
- /**
- * Adds the given callback to the list of callbacks called when checking containers.
- */
- addContainerCheckCallback(callback) {
- if (typeof callback !== "function") {
- throw new TypeError("Expected a valid callback for parameter 'callback'.");
+ const maxlength = validatedField.getAttribute("maxlength");
+ if (maxlength) {
+ properties.set("maxlength", maxlength);
+ validatedField.removeAttribute("maxlength");
}
- EventHandler.add("com.woltlab.wcf.form.builder.dependency", "checkContainers", callback);
- },
- /**
- * Registers a new form field dependency.
- */
- addDependency(dependency) {
- const dependentNode = dependency.getDependentNode();
- if (!_nodeDependencies.has(dependentNode.id)) {
- _nodeDependencies.set(dependentNode.id, [dependency]);
+ const min = validatedField.getAttribute("min");
+ if (min) {
+ properties.set("min", min);
+ validatedField.removeAttribute("min");
}
- else {
- _nodeDependencies.get(dependentNode.id).push(dependency);
+ if (validatedField.required) {
+ properties.set("required", "true");
+ validatedField.removeAttribute("required");
}
- dependency.getFields().forEach((field) => {
- const id = Util_1.default.identify(field);
- if (!_fields.has(id)) {
- _fields.set(id, field);
- if (field.tagName === "INPUT" &&
- (field.type === "checkbox" ||
- field.type === "radio" ||
- field.type === "hidden")) {
- field.addEventListener("change", () => this.checkDependencies());
- }
- else {
- field.addEventListener("input", () => this.checkDependencies());
- }
+ _validatedFieldProperties.set(validatedField, properties);
+ });
+ }
+ /**
+ * Shows the given node because of its own dependencies.
+ */
+ function _show(node) {
+ node.style.display = "block";
+ _dependencyHiddenNodes.delete(node);
+ // also show tab menu entry
+ if (node.classList.contains("tabMenuContent")) {
+ node
+ .parentNode.querySelector(".tabMenu")
+ .querySelectorAll("li")
+ .forEach((tabLink) => {
+ if (tabLink.dataset.name === node.dataset.name) {
+ tabLink.style.display = "block";
}
});
- },
- /**
- * Checks the containers for their availability.
- *
- * If this function is called while containers are currently checked, the containers
- * will be checked after the current check has been finished completely.
- */
- checkContainers() {
- // check if containers are currently being checked
- if (_checkingContainers === true) {
- // and if that is the case, calling this method indicates, that after the current round,
- // containters should be checked to properly propagate changes in children to their parents
- _checkContainersAgain = true;
- return;
+ }
+ node.querySelectorAll("input, select").forEach((validatedField) => {
+ // if a container is shown, ignore all fields that
+ // have a hidden parent element within the container
+ let parentNode = validatedField.parentNode;
+ while (parentNode !== node && parentNode.style.getPropertyValue("display") !== "none") {
+ parentNode = parentNode.parentNode;
}
- // starting to check containers also resets the flag to check containers again after the current check
- _checkingContainers = true;
- _checkContainersAgain = false;
- EventHandler.fire("com.woltlab.wcf.form.builder.dependency", "checkContainers");
- // finish checking containers and check if containters should be checked again
- _checkingContainers = false;
- if (_checkContainersAgain) {
- this.checkContainers();
+ if (parentNode === node && _validatedFieldProperties.has(validatedField)) {
+ const properties = _validatedFieldProperties.get(validatedField);
+ if (properties.has("max")) {
+ validatedField.setAttribute("max", properties.get("max"));
+ }
+ if (properties.has("maxlength")) {
+ validatedField.setAttribute("maxlength", properties.get("maxlength"));
+ }
+ if (properties.has("min")) {
+ validatedField.setAttribute("min", properties.get("min"));
+ }
+ if (properties.has("required")) {
+ validatedField.setAttribute("required", "");
+ }
+ _validatedFieldProperties.delete(validatedField);
}
- },
- /**
- * Checks if all dependencies are met.
- */
- checkDependencies() {
- const obsoleteNodeIds = [];
- _nodeDependencies.forEach((nodeDependencies, nodeId) => {
- const dependentNode = document.getElementById(nodeId);
- if (dependentNode === null) {
- obsoleteNodeIds.push(nodeId);
- return;
+ });
+ }
+ /**
+ * Adds the given callback to the list of callbacks called when checking containers.
+ */
+ function addContainerCheckCallback(callback) {
+ if (typeof callback !== "function") {
+ throw new TypeError("Expected a valid callback for parameter 'callback'.");
+ }
+ EventHandler.add("com.woltlab.wcf.form.builder.dependency", "checkContainers", callback);
+ }
+ exports.addContainerCheckCallback = addContainerCheckCallback;
+ /**
+ * Registers a new form field dependency.
+ */
+ function addDependency(dependency) {
+ const dependentNode = dependency.getDependentNode();
+ if (!_nodeDependencies.has(dependentNode.id)) {
+ _nodeDependencies.set(dependentNode.id, [dependency]);
+ }
+ else {
+ _nodeDependencies.get(dependentNode.id).push(dependency);
+ }
+ dependency.getFields().forEach((field) => {
+ const id = Util_1.default.identify(field);
+ if (!_fields.has(id)) {
+ _fields.set(id, field);
+ if (field.tagName === "INPUT" &&
+ (field.type === "checkbox" ||
+ field.type === "radio" ||
+ field.type === "hidden")) {
+ field.addEventListener("change", () => checkDependencies());
}
- let dependenciesMet = true;
- nodeDependencies.forEach((dependency) => {
- if (!dependency.checkDependency()) {
- this._hide(dependentNode);
- dependenciesMet = false;
- }
- });
- if (dependenciesMet) {
- this._show(dependentNode);
+ else {
+ field.addEventListener("input", () => checkDependencies());
}
- });
- obsoleteNodeIds.forEach((id) => _nodeDependencies.delete(id));
- this.checkContainers();
- },
- /**
- * Returns `true` if the given node has been hidden because of its own dependencies.
- */
- isHiddenByDependencies(node) {
- if (_dependencyHiddenNodes.has(node)) {
- return true;
}
- let returnValue = false;
- _dependencyHiddenNodes.forEach((hiddenNode) => {
- if (node.contains(hiddenNode)) {
- returnValue = true;
+ });
+ }
+ exports.addDependency = addDependency;
+ /**
+ * Checks the containers for their availability.
+ *
+ * If this function is called while containers are currently checked, the containers
+ * will be checked after the current check has been finished completely.
+ */
+ function checkContainers() {
+ // check if containers are currently being checked
+ if (_checkingContainers === true) {
+ // and if that is the case, calling this method indicates, that after the current round,
+ // containters should be checked to properly propagate changes in children to their parents
+ _checkContainersAgain = true;
+ return;
+ }
+ // starting to check containers also resets the flag to check containers again after the current check
+ _checkingContainers = true;
+ _checkContainersAgain = false;
+ EventHandler.fire("com.woltlab.wcf.form.builder.dependency", "checkContainers");
+ // finish checking containers and check if containters should be checked again
+ _checkingContainers = false;
+ if (_checkContainersAgain) {
+ checkContainers();
+ }
+ }
+ exports.checkContainers = checkContainers;
+ /**
+ * Checks if all dependencies are met.
+ */
+ function checkDependencies() {
+ const obsoleteNodeIds = [];
+ _nodeDependencies.forEach((nodeDependencies, nodeId) => {
+ const dependentNode = document.getElementById(nodeId);
+ if (dependentNode === null) {
+ obsoleteNodeIds.push(nodeId);
+ return;
+ }
+ let dependenciesMet = true;
+ nodeDependencies.forEach((dependency) => {
+ if (!dependency.checkDependency()) {
+ _hide(dependentNode);
+ dependenciesMet = false;
}
});
- return returnValue;
- },
- /**
- * Registers the form with the given id with the dependency manager.
- */
- register(formId) {
- const form = document.getElementById(formId);
- if (form === null) {
- throw new Error("Unknown element with id '" + formId + "'");
+ if (dependenciesMet) {
+ _show(dependentNode);
}
- if (_forms.has(form)) {
- throw new Error("Form with id '" + formId + "' has already been registered.");
+ });
+ obsoleteNodeIds.forEach((id) => _nodeDependencies.delete(id));
+ checkContainers();
+ }
+ exports.checkDependencies = checkDependencies;
+ /**
+ * Returns `true` if the given node has been hidden because of its own dependencies.
+ */
+ function isHiddenByDependencies(node) {
+ if (_dependencyHiddenNodes.has(node)) {
+ return true;
+ }
+ let returnValue = false;
+ _dependencyHiddenNodes.forEach((hiddenNode) => {
+ if (node.contains(hiddenNode)) {
+ returnValue = true;
}
- _forms.add(form);
- },
- /**
- * Unregisters the form with the given id and all of its dependencies.
- */
- unregister(formId) {
- const form = document.getElementById(formId);
- if (form === null) {
- throw new Error("Unknown element with id '" + formId + "'");
+ });
+ return returnValue;
+ }
+ exports.isHiddenByDependencies = isHiddenByDependencies;
+ /**
+ * Registers the form with the given id with the dependency manager.
+ */
+ function register(formId) {
+ const form = document.getElementById(formId);
+ if (form === null) {
+ throw new Error("Unknown element with id '" + formId + "'");
+ }
+ if (_forms.has(form)) {
+ throw new Error("Form with id '" + formId + "' has already been registered.");
+ }
+ _forms.add(form);
+ }
+ exports.register = register;
+ /**
+ * Unregisters the form with the given id and all of its dependencies.
+ */
+ function unregister(formId) {
+ const form = document.getElementById(formId);
+ if (form === null) {
+ throw new Error("Unknown element with id '" + formId + "'");
+ }
+ if (!_forms.has(form)) {
+ throw new Error("Form with id '" + formId + "' has not been registered.");
+ }
+ _forms.delete(form);
+ _dependencyHiddenNodes.forEach((hiddenNode) => {
+ if (form.contains(hiddenNode)) {
+ _dependencyHiddenNodes.delete(hiddenNode);
}
- if (!_forms.has(form)) {
- throw new Error("Form with id '" + formId + "' has not been registered.");
+ });
+ _nodeDependencies.forEach((dependencies, nodeId) => {
+ if (form.contains(document.getElementById(nodeId))) {
+ _nodeDependencies.delete(nodeId);
}
- _forms.delete(form);
- _dependencyHiddenNodes.forEach((hiddenNode) => {
- if (form.contains(hiddenNode)) {
- _dependencyHiddenNodes.delete(hiddenNode);
- }
- });
- _nodeDependencies.forEach((dependencies, nodeId) => {
- if (form.contains(document.getElementById(nodeId))) {
- _nodeDependencies.delete(nodeId);
- }
- dependencies.forEach((dependency) => {
- dependency.getFields().forEach((field) => {
- _fields.delete(field.id);
- _validatedFieldProperties.delete(field);
- });
+ dependencies.forEach((dependency) => {
+ dependency.getFields().forEach((field) => {
+ _fields.delete(field.id);
+ _validatedFieldProperties.delete(field);
});
});
- },
- };
- Core.enableLegacyInheritance(Manager);
- return Manager;
+ });
+ }
+ exports.unregister = unregister;
});
* @module WoltLabSuite/Core/Form/Builder/Manager
* @since 5.2
*/
-define(["require", "exports", "tslib", "../../Core", "../../Event/Handler", "./Field/Field", "./Field/Dependency/Manager"], function (require, exports, tslib_1, Core, EventHandler, Field_1, Manager_1) {
+define(["require", "exports", "tslib", "../../Core", "../../Event/Handler", "./Field/Field", "./Field/Dependency/Manager"], function (require, exports, tslib_1, Core, EventHandler, Field_1, DependencyManager) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.unregisterForm = exports.registerForm = exports.registerField = exports.hasForm = exports.hasField = exports.getForm = exports.getField = exports.getData = void 0;
Core = tslib_1.__importStar(Core);
EventHandler = tslib_1.__importStar(EventHandler);
Field_1 = tslib_1.__importDefault(Field_1);
- Manager_1 = tslib_1.__importDefault(Manager_1);
+ DependencyManager = tslib_1.__importStar(DependencyManager);
const _fields = new Map();
const _forms = new Map();
/**
field.destroy();
});
_fields.delete(formId);
- Manager_1.default.unregister(formId);
+ DependencyManager.unregister(formId);
EventHandler.fire("WoltLabSuite/Core/Form/Builder/Manager", "afterUnregisterForm", {
formId: formId,
});
protected readonly _labelChooser: HTMLElement;
protected readonly _options: LabelFormFieldOptions;
- constructor(fieldId: string, labelId: string, options: LabelFormFieldOptions) {
+ constructor(fieldId: string, labelId: string, options: Partial<LabelFormFieldOptions>) {
this._formFieldContainer = document.getElementById(fieldId + "Container")!;
this._labelChooser = this._formFieldContainer.getElementsByClassName("labelChooser")[0] as HTMLElement;
this._options = Core.extend(
/**
* Saves the rating associated with the clicked rating element.
*/
- _listItemClick(event: Event): void {
+ protected _listItemClick(event: Event): void {
const target = event.currentTarget as HTMLElement;
this._input.value = target.dataset.rating!;
/**
* Updates the rating UI when hovering over a rating element.
*/
- _listItemMouseEnter(event: Event): void {
+ protected _listItemMouseEnter(event: Event): void {
const target = event.currentTarget as HTMLElement;
const currentRating = target.dataset.rating!;
* Updates the rating UI when leaving a rating element by changing all rating elements
* to their default state.
*/
- _listItemMouseLeave(): void {
+ protected _listItemMouseLeave(): void {
this._ratingElements.forEach((ratingElement) => {
const icon = ratingElement.getElementsByClassName("icon")[0]! as HTMLElement;
/**
* Handles clicks on meta buttons.
*/
- _metaButtonClick(event: Event): void {
+ protected _metaButtonClick(event: Event): void {
const target = event.currentTarget as HTMLElement;
if (target.dataset.action === "removeRating") {
this._input.value = "";
/**
* Updates the rating UI by changing the rating elements to the stored rating state.
*/
- _restoreRating(): void {
+ protected _restoreRating(): void {
this._ratingElements.forEach((ratingElement, rating) => {
const icon = ratingElement.getElementsByClassName("icon")[0]! as HTMLElement;
/**
* Toggles the state of the given icon based on the given state parameter.
*/
- _toggleIcon(icon: HTMLElement, active = false): void {
+ protected _toggleIcon(icon: HTMLElement, active = false): void {
if (active) {
icon.classList.remove(...this._defaultCssClasses);
icon.classList.add(...this._activeCssClasses);
* @since 5.2
*/
-import Manager from "./Manager";
+import * as DependencyManager from "./Manager";
import * as Core from "../../../../Core";
abstract class FormBuilderFormFieldDependency {
}
}
- Manager.addDependency(this);
+ DependencyManager.addDependency(this);
}
}
* @since 5.2
*/
-import DependencyManager from "../Manager";
+import * as DependencyManager from "../Manager";
import * as Core from "../../../../../Core";
-class Abstract {
+abstract class Abstract {
protected _container: HTMLElement;
constructor(containerId: string) {
import Abstract from "./Abstract";
import * as Core from "../../../../../Core";
-import DependencyManager from "../Manager";
+import * as DependencyManager from "../Manager";
class Default extends Abstract {
public checkContainer(): void {
*/
import Abstract from "./Abstract";
-import DependencyManager from "../Manager";
+import * as DependencyManager from "../Manager";
import * as DomUtil from "../../../../../Dom/Util";
import * as UiTabMenu from "../../../../../Ui/TabMenu";
import * as Core from "../../../../../Core";
*/
import Abstract from "./Abstract";
-import DependencyManager from "../Manager";
+import * as DependencyManager from "../Manager";
import * as DomUtil from "../../../../../Dom/Util";
import * as UiTabMenu from "../../../../../Ui/TabMenu";
import * as Core from "../../../../../Core";
*/
import Abstract from "./Abstract";
-import Manager from "./Manager";
-import * as Core from "../../../../Core";
+import * as DependencyManager from "./Manager";
-class IsNotClicked extends Abstract {
+export class IsNotClicked extends Abstract {
constructor(dependentElementId: string, fieldId: string) {
super(dependentElementId, fieldId);
this._field.addEventListener("click", () => {
this._field.dataset.isClicked = "1";
- Manager.checkDependencies();
+ DependencyManager.checkDependencies();
});
}
}
}
-Core.enableLegacyInheritance(IsNotClicked);
-
-export = IsNotClicked;
+export default IsNotClicked;
import DomUtil from "../../../../Dom/Util";
import * as EventHandler from "../../../../Event/Handler";
import FormBuilderFormFieldDependency from "./Abstract";
-import * as DomTraverse from "../../../../Dom/Traverse";
-import * as Core from "../../../../Core";
type PropertiesMap = Map<string, string>;
type Callback = (...args: any[]) => void;
-const Manager = {
- /**
- * Hides the given node because of its own dependencies.
- */
- _hide(node: HTMLElement): void {
- node.style.display = "none";
- _dependencyHiddenNodes.add(node);
-
- // also hide tab menu entry
- if (node.classList.contains("tabMenuContent")) {
- node
- .parentNode!.querySelector(".tabMenu")!
- .querySelectorAll("li")
- .forEach((tabLink) => {
- if (tabLink.dataset.name === node.dataset.name) {
- tabLink.style.display = "none";
- }
- });
- }
-
- node.querySelectorAll("[max], [maxlength], [min], [required]").forEach((validatedField: HTMLInputElement) => {
- const properties = new Map<string, string>();
-
- const max = validatedField.getAttribute("max");
- if (max) {
- properties.set("max", max);
- validatedField.removeAttribute("max");
- }
+/**
+ * Hides the given node because of its own dependencies.
+ */
+function _hide(node: HTMLElement): void {
+ node.style.display = "none";
+ _dependencyHiddenNodes.add(node);
+
+ // also hide tab menu entry
+ if (node.classList.contains("tabMenuContent")) {
+ node
+ .parentNode!.querySelector(".tabMenu")!
+ .querySelectorAll("li")
+ .forEach((tabLink) => {
+ if (tabLink.dataset.name === node.dataset.name) {
+ tabLink.style.display = "none";
+ }
+ });
+ }
- const maxlength = validatedField.getAttribute("maxlength");
- if (maxlength) {
- properties.set("maxlength", maxlength);
- validatedField.removeAttribute("maxlength");
- }
+ node.querySelectorAll("[max], [maxlength], [min], [required]").forEach((validatedField: HTMLInputElement) => {
+ const properties = new Map<string, string>();
- const min = validatedField.getAttribute("min");
- if (min) {
- properties.set("min", min);
- validatedField.removeAttribute("min");
- }
+ const max = validatedField.getAttribute("max");
+ if (max) {
+ properties.set("max", max);
+ validatedField.removeAttribute("max");
+ }
- if (validatedField.required) {
- properties.set("required", "true");
- validatedField.removeAttribute("required");
- }
+ const maxlength = validatedField.getAttribute("maxlength");
+ if (maxlength) {
+ properties.set("maxlength", maxlength);
+ validatedField.removeAttribute("maxlength");
+ }
- _validatedFieldProperties.set(validatedField, properties);
- });
- },
-
- /**
- * Shows the given node because of its own dependencies.
- */
- _show(node: HTMLElement): void {
- node.style.display = "block";
- _dependencyHiddenNodes.delete(node);
-
- // also show tab menu entry
- if (node.classList.contains("tabMenuContent")) {
- node
- .parentNode!.querySelector(".tabMenu")!
- .querySelectorAll("li")
- .forEach((tabLink) => {
- if (tabLink.dataset.name === node.dataset.name) {
- tabLink.style.display = "block";
- }
- });
+ const min = validatedField.getAttribute("min");
+ if (min) {
+ properties.set("min", min);
+ validatedField.removeAttribute("min");
}
- node.querySelectorAll("input, select").forEach((validatedField: HTMLInputElement | HTMLSelectElement) => {
- // if a container is shown, ignore all fields that
- // have a hidden parent element within the container
- let parentNode = validatedField.parentNode! as HTMLElement;
- while (parentNode !== node && parentNode.style.getPropertyValue("display") !== "none") {
- parentNode = parentNode.parentNode! as HTMLElement;
- }
+ if (validatedField.required) {
+ properties.set("required", "true");
+ validatedField.removeAttribute("required");
+ }
- if (parentNode === node && _validatedFieldProperties.has(validatedField)) {
- const properties = _validatedFieldProperties.get(validatedField)!;
+ _validatedFieldProperties.set(validatedField, properties);
+ });
+}
- if (properties.has("max")) {
- validatedField.setAttribute("max", properties.get("max")!);
- }
- if (properties.has("maxlength")) {
- validatedField.setAttribute("maxlength", properties.get("maxlength")!);
- }
- if (properties.has("min")) {
- validatedField.setAttribute("min", properties.get("min")!);
- }
- if (properties.has("required")) {
- validatedField.setAttribute("required", "");
+/**
+ * Shows the given node because of its own dependencies.
+ */
+function _show(node: HTMLElement): void {
+ node.style.display = "block";
+ _dependencyHiddenNodes.delete(node);
+
+ // also show tab menu entry
+ if (node.classList.contains("tabMenuContent")) {
+ node
+ .parentNode!.querySelector(".tabMenu")!
+ .querySelectorAll("li")
+ .forEach((tabLink) => {
+ if (tabLink.dataset.name === node.dataset.name) {
+ tabLink.style.display = "block";
}
-
- _validatedFieldProperties.delete(validatedField);
- }
- });
- },
-
- /**
- * Adds the given callback to the list of callbacks called when checking containers.
- */
- addContainerCheckCallback(callback: Callback): void {
- if (typeof callback !== "function") {
- throw new TypeError("Expected a valid callback for parameter 'callback'.");
+ });
+ }
+
+ node.querySelectorAll("input, select").forEach((validatedField: HTMLInputElement | HTMLSelectElement) => {
+ // if a container is shown, ignore all fields that
+ // have a hidden parent element within the container
+ let parentNode = validatedField.parentNode! as HTMLElement;
+ while (parentNode !== node && parentNode.style.getPropertyValue("display") !== "none") {
+ parentNode = parentNode.parentNode! as HTMLElement;
}
- EventHandler.add("com.woltlab.wcf.form.builder.dependency", "checkContainers", callback);
- },
-
- /**
- * Registers a new form field dependency.
- */
- addDependency(dependency: FormBuilderFormFieldDependency): void {
- const dependentNode = dependency.getDependentNode();
- if (!_nodeDependencies.has(dependentNode.id)) {
- _nodeDependencies.set(dependentNode.id, [dependency]);
- } else {
- _nodeDependencies.get(dependentNode.id)!.push(dependency);
- }
+ if (parentNode === node && _validatedFieldProperties.has(validatedField)) {
+ const properties = _validatedFieldProperties.get(validatedField)!;
- dependency.getFields().forEach((field) => {
- const id = DomUtil.identify(field);
-
- if (!_fields.has(id)) {
- _fields.set(id, field);
-
- if (
- field.tagName === "INPUT" &&
- ((field as HTMLInputElement).type === "checkbox" ||
- (field as HTMLInputElement).type === "radio" ||
- (field as HTMLInputElement).type === "hidden")
- ) {
- field.addEventListener("change", () => this.checkDependencies());
- } else {
- field.addEventListener("input", () => this.checkDependencies());
- }
+ if (properties.has("max")) {
+ validatedField.setAttribute("max", properties.get("max")!);
+ }
+ if (properties.has("maxlength")) {
+ validatedField.setAttribute("maxlength", properties.get("maxlength")!);
+ }
+ if (properties.has("min")) {
+ validatedField.setAttribute("min", properties.get("min")!);
+ }
+ if (properties.has("required")) {
+ validatedField.setAttribute("required", "");
}
- });
- },
-
- /**
- * Checks the containers for their availability.
- *
- * If this function is called while containers are currently checked, the containers
- * will be checked after the current check has been finished completely.
- */
- checkContainers(): void {
- // check if containers are currently being checked
- if (_checkingContainers === true) {
- // and if that is the case, calling this method indicates, that after the current round,
- // containters should be checked to properly propagate changes in children to their parents
- _checkContainersAgain = true;
- return;
+ _validatedFieldProperties.delete(validatedField);
}
+ });
+}
- // starting to check containers also resets the flag to check containers again after the current check
- _checkingContainers = true;
- _checkContainersAgain = false;
+/**
+ * Adds the given callback to the list of callbacks called when checking containers.
+ */
+export function addContainerCheckCallback(callback: Callback): void {
+ if (typeof callback !== "function") {
+ throw new TypeError("Expected a valid callback for parameter 'callback'.");
+ }
- EventHandler.fire("com.woltlab.wcf.form.builder.dependency", "checkContainers");
+ EventHandler.add("com.woltlab.wcf.form.builder.dependency", "checkContainers", callback);
+}
- // finish checking containers and check if containters should be checked again
- _checkingContainers = false;
- if (_checkContainersAgain) {
- this.checkContainers();
+/**
+ * Registers a new form field dependency.
+ */
+export function addDependency(dependency: FormBuilderFormFieldDependency): void {
+ const dependentNode = dependency.getDependentNode();
+ if (!_nodeDependencies.has(dependentNode.id)) {
+ _nodeDependencies.set(dependentNode.id, [dependency]);
+ } else {
+ _nodeDependencies.get(dependentNode.id)!.push(dependency);
+ }
+
+ dependency.getFields().forEach((field) => {
+ const id = DomUtil.identify(field);
+
+ if (!_fields.has(id)) {
+ _fields.set(id, field);
+
+ if (
+ field.tagName === "INPUT" &&
+ ((field as HTMLInputElement).type === "checkbox" ||
+ (field as HTMLInputElement).type === "radio" ||
+ (field as HTMLInputElement).type === "hidden")
+ ) {
+ field.addEventListener("change", () => checkDependencies());
+ } else {
+ field.addEventListener("input", () => checkDependencies());
+ }
}
- },
+ });
+}
- /**
- * Checks if all dependencies are met.
- */
- checkDependencies(): void {
- const obsoleteNodeIds: string[] = [];
+/**
+ * Checks the containers for their availability.
+ *
+ * If this function is called while containers are currently checked, the containers
+ * will be checked after the current check has been finished completely.
+ */
+export function checkContainers(): void {
+ // check if containers are currently being checked
+ if (_checkingContainers === true) {
+ // and if that is the case, calling this method indicates, that after the current round,
+ // containters should be checked to properly propagate changes in children to their parents
+ _checkContainersAgain = true;
- _nodeDependencies.forEach((nodeDependencies, nodeId) => {
- const dependentNode = document.getElementById(nodeId);
- if (dependentNode === null) {
- obsoleteNodeIds.push(nodeId);
+ return;
+ }
- return;
- }
+ // starting to check containers also resets the flag to check containers again after the current check
+ _checkingContainers = true;
+ _checkContainersAgain = false;
- let dependenciesMet = true;
- nodeDependencies.forEach((dependency) => {
- if (!dependency.checkDependency()) {
- this._hide(dependentNode);
- dependenciesMet = false;
- }
- });
+ EventHandler.fire("com.woltlab.wcf.form.builder.dependency", "checkContainers");
- if (dependenciesMet) {
- this._show(dependentNode);
- }
- });
+ // finish checking containers and check if containters should be checked again
+ _checkingContainers = false;
+ if (_checkContainersAgain) {
+ checkContainers();
+ }
+}
- obsoleteNodeIds.forEach((id) => _nodeDependencies.delete(id));
+/**
+ * Checks if all dependencies are met.
+ */
+export function checkDependencies(): void {
+ const obsoleteNodeIds: string[] = [];
- this.checkContainers();
- },
+ _nodeDependencies.forEach((nodeDependencies, nodeId) => {
+ const dependentNode = document.getElementById(nodeId);
+ if (dependentNode === null) {
+ obsoleteNodeIds.push(nodeId);
- /**
- * Returns `true` if the given node has been hidden because of its own dependencies.
- */
- isHiddenByDependencies(node: HTMLElement): boolean {
- if (_dependencyHiddenNodes.has(node)) {
- return true;
+ return;
}
- let returnValue = false;
- _dependencyHiddenNodes.forEach((hiddenNode) => {
- if (node.contains(hiddenNode)) {
- returnValue = true;
+ let dependenciesMet = true;
+ nodeDependencies.forEach((dependency) => {
+ if (!dependency.checkDependency()) {
+ _hide(dependentNode);
+ dependenciesMet = false;
}
});
- return returnValue;
- },
+ if (dependenciesMet) {
+ _show(dependentNode);
+ }
+ });
- /**
- * Registers the form with the given id with the dependency manager.
- */
- register(formId: string): void {
- const form = document.getElementById(formId);
+ obsoleteNodeIds.forEach((id) => _nodeDependencies.delete(id));
- if (form === null) {
- throw new Error("Unknown element with id '" + formId + "'");
- }
+ checkContainers();
+}
- if (_forms.has(form)) {
- throw new Error("Form with id '" + formId + "' has already been registered.");
+/**
+ * Returns `true` if the given node has been hidden because of its own dependencies.
+ */
+export function isHiddenByDependencies(node: HTMLElement): boolean {
+ if (_dependencyHiddenNodes.has(node)) {
+ return true;
+ }
+
+ let returnValue = false;
+ _dependencyHiddenNodes.forEach((hiddenNode) => {
+ if (node.contains(hiddenNode)) {
+ returnValue = true;
}
+ });
- _forms.add(form);
- },
+ return returnValue;
+}
- /**
- * Unregisters the form with the given id and all of its dependencies.
- */
- unregister(formId: string): void {
- const form = document.getElementById(formId);
+/**
+ * Registers the form with the given id with the dependency manager.
+ */
+export function register(formId: string): void {
+ const form = document.getElementById(formId);
- if (form === null) {
- throw new Error("Unknown element with id '" + formId + "'");
- }
+ if (form === null) {
+ throw new Error("Unknown element with id '" + formId + "'");
+ }
- if (!_forms.has(form)) {
- throw new Error("Form with id '" + formId + "' has not been registered.");
- }
+ if (_forms.has(form)) {
+ throw new Error("Form with id '" + formId + "' has already been registered.");
+ }
- _forms.delete(form);
+ _forms.add(form);
+}
- _dependencyHiddenNodes.forEach((hiddenNode) => {
- if (form.contains(hiddenNode)) {
- _dependencyHiddenNodes.delete(hiddenNode);
- }
- });
- _nodeDependencies.forEach((dependencies, nodeId) => {
- if (form.contains(document.getElementById(nodeId))) {
- _nodeDependencies.delete(nodeId);
- }
+/**
+ * Unregisters the form with the given id and all of its dependencies.
+ */
+export function unregister(formId: string): void {
+ const form = document.getElementById(formId);
- dependencies.forEach((dependency) => {
- dependency.getFields().forEach((field) => {
- _fields.delete(field.id);
+ if (form === null) {
+ throw new Error("Unknown element with id '" + formId + "'");
+ }
- _validatedFieldProperties.delete(field);
- });
- });
- });
- },
-};
+ if (!_forms.has(form)) {
+ throw new Error("Form with id '" + formId + "' has not been registered.");
+ }
+
+ _forms.delete(form);
+
+ _dependencyHiddenNodes.forEach((hiddenNode) => {
+ if (form.contains(hiddenNode)) {
+ _dependencyHiddenNodes.delete(hiddenNode);
+ }
+ });
+ _nodeDependencies.forEach((dependencies, nodeId) => {
+ if (form.contains(document.getElementById(nodeId))) {
+ _nodeDependencies.delete(nodeId);
+ }
-Core.enableLegacyInheritance(Manager);
+ dependencies.forEach((dependency) => {
+ dependency.getFields().forEach((field) => {
+ _fields.delete(field.id);
-export = Manager;
+ _validatedFieldProperties.delete(field);
+ });
+ });
+ });
+}
import * as Core from "../../Core";
import * as EventHandler from "../../Event/Handler";
import Field from "./Field/Field";
-import DependencyManager from "./Field/Dependency/Manager";
+import * as DependencyManager from "./Field/Dependency/Manager";
import { FormBuilderData } from "./Data";
type FormId = string;