2023-08-21 04:17:16 -04:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "utf-8" >
< title > JSDoc: Source: widgets/basic_widget.js< / title >
< script src = "scripts/prettify/prettify.js" > < / script >
< script src = "scripts/prettify/lang-css.js" > < / script >
<!-- [if lt IE 9]>
< script src = "//html5shiv.googlecode.com/svn/trunk/html5.js" > < / script >
<![endif]-->
< link type = "text/css" rel = "stylesheet" href = "styles/prettify-tomorrow.css" >
< link type = "text/css" rel = "stylesheet" href = "styles/jsdoc-default.css" >
< / head >
< body >
< div id = "main" >
< h1 class = "page-title" > Source: widgets/basic_widget.js< / h1 >
< section >
< article >
< pre class = "prettyprint source linenums" > < code > import Component from "../components/component.js";
2024-12-11 18:31:29 +02:00
import froca from "../services/froca.js";
import { t } from "../services/i18n.js";
import toastService from "../services/toast.js";
2023-08-21 04:17:16 -04:00
/**
* This is the base widget for all other widgets.
2023-11-03 12:23:14 +01:00
*
2023-08-21 04:17:16 -04:00
* For information on using widgets, see the tutorial {@tutorial widget_basics}.
*/
class BasicWidget extends Component {
constructor() {
super();
this.attrs = {
style: ''
};
this.classes = [];
this.children = [];
this.childPositionCounter = 10;
}
child(...components) {
if (!components) {
return this;
}
super.child(...components);
for (const component of components) {
if (component.position === undefined) {
component.position = this.childPositionCounter;
this.childPositionCounter += 10;
}
}
2023-11-03 12:23:14 +01:00
this.children.sort((a, b) => a.position - b.position);
2023-08-21 04:17:16 -04:00
return this;
}
2024-12-11 18:31:29 +02:00
/**
* Conditionally adds the given components as children to this component.
*
* @param {boolean} condition whether to add the components.
* @param {...any} components the components to be added as children to this component provided the condition is truthy.
* @returns self for chaining.
*/
optChild(condition, ...components) {
if (condition) {
return this.child(...components);
} else {
return this;
}
}
2023-08-21 04:17:16 -04:00
id(id) {
this.attrs.id = id;
return this;
}
class(className) {
this.classes.push(className);
return this;
}
2024-12-11 18:31:29 +02:00
/**
* Sets the CSS attribute of the given name to the given value.
*
* @param {string} name the name of the CSS attribute to set (e.g. `padding-left`).
* @param {string} value the value of the CSS attribute to set (e.g. `12px`).
* @returns self for chaining.
*/
2023-08-21 04:17:16 -04:00
css(name, value) {
this.attrs.style += `${name}: ${value};`;
return this;
}
2024-12-11 18:31:29 +02:00
/**
* Sets the CSS attribute of the given name to the given value, but only if the condition provided is truthy.
*
* @param {boolean} condition `true` in order to apply the CSS, `false` to ignore it.
* @param {string} name the name of the CSS attribute to set (e.g. `padding-left`).
* @param {string} value the value of the CSS attribute to set (e.g. `12px`).
* @returns self for chaining.
*/
optCss(condition, name, value) {
if (condition) {
return this.css(name, value);
}
return this;
}
2023-08-21 04:17:16 -04:00
contentSized() {
this.css("contain", "none");
return this;
}
collapsible() {
this.css('min-height', '0');
this.css('min-width', '0');
return this;
}
filling() {
this.css('flex-grow', '1');
return this;
}
/**
* Accepts a string of CSS to add with the widget.
2023-11-03 12:23:14 +01:00
* @param {string} block
2023-08-21 04:17:16 -04:00
* @returns {this} for chaining
*/
cssBlock(block) {
this.cssEl = block;
return this;
}
render() {
2024-12-11 18:31:29 +02:00
try {
this.doRender();
} catch (e) {
this.logRenderingError(e);
}
2023-08-21 04:17:16 -04:00
this.$widget.attr('data-component-id', this.componentId);
2023-11-03 12:23:14 +01:00
this.$widget
.addClass('component')
2023-08-21 04:17:16 -04:00
.prop('component', this);
if (!this.isEnabled()) {
this.toggleInt(false);
}
if (this.cssEl) {
const css = this.cssEl.trim().startsWith('< style>') ? this.cssEl : `< style>${this.cssEl}< /style>`;
this.$widget.append(css);
}
for (const key in this.attrs) {
if (key === 'style') {
if (this.attrs[key]) {
let style = this.$widget.attr('style');
style = style ? `${style}; ${this.attrs[key]}` : this.attrs[key];
this.$widget.attr(key, style);
}
}
else {
this.$widget.attr(key, this.attrs[key]);
}
}
for (const className of this.classes) {
this.$widget.addClass(className);
}
return this.$widget;
}
2024-12-11 18:31:29 +02:00
logRenderingError(e) {
console.log("Got issue in widget ", this);
console.error(e);
let noteId = this._noteId;
if (this._noteId) {
froca.getNote(noteId, true).then((note) => {
toastService.showPersistent({
title: t("toast.widget-error.title"),
icon: "alert",
message: t("toast.widget-error.message-custom", {
id: noteId,
title: note.title,
message: e.message
})
});
});
return;
}
toastService.showPersistent({
title: t("toast.widget-error.title"),
icon: "alert",
message: t("toast.widget-error.message-unknown", {
message: e.message
})
});
}
/**
* Indicates if the widget is enabled. Widgets are enabled by default. Generally setting this to `false` will cause the widget not to be displayed, however it will still be available on the DOM but hidden.
* @returns whether the widget is enabled.
*/
2023-08-21 04:17:16 -04:00
isEnabled() {
return true;
}
/**
* Method used for rendering the widget.
2023-11-03 12:23:14 +01:00
*
2023-08-21 04:17:16 -04:00
* Your class should override this method.
2023-11-03 12:23:14 +01:00
* The method is expected to create a this.$widget containing jQuery object
2023-08-21 04:17:16 -04:00
*/
doRender() {}
toggleInt(show) {
this.$widget.toggleClass('hidden-int', !show);
}
isHiddenInt() {
return this.$widget.hasClass('hidden-int');
}
toggleExt(show) {
this.$widget.toggleClass('hidden-ext', !show);
}
isHiddenExt() {
return this.$widget.hasClass('hidden-ext');
}
canBeShown() {
return !this.isHiddenInt() & & !this.isHiddenExt();
}
isVisible() {
return this.$widget.is(":visible");
}
getPosition() {
return this.position;
}
remove() {
if (this.$widget) {
this.$widget.remove();
}
}
getClosestNtxId() {
if (this.$widget) {
return this.$widget.closest("[data-ntx-id]").attr("data-ntx-id");
}
else {
return null;
}
}
cleanup() {}
}
export default BasicWidget;
< / code > < / pre >
< / article >
< / section >
< / div >
< nav >
2023-09-25 23:11:24 +02:00
< h2 > < a href = "index.html" > Home< / a > < / h2 > < h3 > Classes< / h3 > < ul > < li > < a href = "BasicWidget.html" > BasicWidget< / a > < / li > < li > < a href = "FAttachment.html" > FAttachment< / a > < / li > < li > < a href = "FAttribute.html" > FAttribute< / a > < / li > < li > < a href = "FBranch.html" > FBranch< / a > < / li > < li > < a href = "FNote.html" > FNote< / a > < / li > < li > < a href = "FrontendScriptApi.html" > FrontendScriptApi< / a > < / li > < li > < a href = "NoteContextAwareWidget.html" > NoteContextAwareWidget< / a > < / li > < li > < a href = "RightPanelWidget.html" > RightPanelWidget< / a > < / li > < / ul > < h3 > Global< / h3 > < ul > < li > < a href = "global.html#api" > api< / a > < / li > < li > < a href = "global.html#getJsonContent" > getJsonContent< / a > < / li > < li > < a href = "global.html#getJsonContentSafely" > getJsonContentSafely< / a > < / li > < / ul >
2023-08-21 04:17:16 -04:00
< / nav >
< br class = "clear" >
< footer >
2024-12-11 18:31:29 +02:00
Documentation generated by < a href = "https://github.com/jsdoc/jsdoc" > JSDoc 4.0.3< / a >
2023-08-21 04:17:16 -04:00
< / footer >
< script > prettyPrint ( ) ; < / script >
< script src = "scripts/linenumber.js" > < / script >
< / body >
< / html >