mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-11-14 16:55:42 +00:00
Add comments to JavaScript and some restructuring
This commit is contained in:
parent
f101a742a9
commit
965f2854b2
@ -1,3 +1,8 @@
|
|||||||
|
// IDEA: Split the App logic into seperate units
|
||||||
|
// - App.Data
|
||||||
|
// - App.IO (name is WIP)
|
||||||
|
// - App.UI
|
||||||
|
|
||||||
App.App = class App {
|
App.App = class App {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.data = {
|
this.data = {
|
||||||
@ -101,4 +106,94 @@ App.App = class App {
|
|||||||
// Apply Patch
|
// Apply Patch
|
||||||
jsonpatch.applyPatch(this.data, filteredPatch);
|
jsonpatch.applyPatch(this.data, filteredPatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.initUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
initUi() {
|
||||||
|
/* Pre-Initialization fixes */
|
||||||
|
// #region
|
||||||
|
|
||||||
|
// Flask-WTF sets the standard HTML maxlength Attribute on input/textarea
|
||||||
|
// elements to specify their maximum length (in characters). Unfortunatly
|
||||||
|
// Materialize won't recognize the maxlength Attribute, instead it uses
|
||||||
|
// the data-length Attribute. It's conversion time :)
|
||||||
|
for (let elem of document.querySelectorAll('input[maxlength], textarea[maxlength]')) {
|
||||||
|
elem.dataset.length = elem.getAttribute('maxlength');
|
||||||
|
elem.removeAttribute('maxlength');
|
||||||
|
}
|
||||||
|
|
||||||
|
// To work around some limitations with the Form setup of Flask-WTF.
|
||||||
|
// HTML option elements with an empty value are considered as placeholder
|
||||||
|
// elements. The user should not be able to actively select these options.
|
||||||
|
// So they get the disabled attribute.
|
||||||
|
for (let optionElement of document.querySelectorAll('option[value=""]')) {
|
||||||
|
optionElement.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Check why we are doing this.
|
||||||
|
for (let optgroupElement of document.querySelectorAll('optgroup[label=""]')) {
|
||||||
|
for (let c of optgroupElement.children) {
|
||||||
|
optgroupElement.parentElement.insertAdjacentElement('afterbegin', c);
|
||||||
|
}
|
||||||
|
optgroupElement.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
/* Initialize Materialize Components */
|
||||||
|
// #region
|
||||||
|
|
||||||
|
// Automatically initialize Materialize Components that do not require
|
||||||
|
// additional configuration.
|
||||||
|
M.AutoInit();
|
||||||
|
|
||||||
|
// CharacterCounters
|
||||||
|
// Materialize didn't include the CharacterCounter plugin within the
|
||||||
|
// AutoInit method (maybe they forgot it?). Anyway... We do it here. :)
|
||||||
|
M.CharacterCounter.init(document.querySelectorAll('input[data-length]:not(.no-autoinit), textarea[data-length]:not(.no-autoinit)'));
|
||||||
|
|
||||||
|
// Header navigation "more" Dropdown.
|
||||||
|
M.Dropdown.init(
|
||||||
|
document.querySelector('#nav-more-dropdown-trigger'),
|
||||||
|
{
|
||||||
|
alignment: 'right',
|
||||||
|
constrainWidth: false,
|
||||||
|
coverTrigger: false
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Manual modal
|
||||||
|
M.Modal.init(
|
||||||
|
document.querySelector('#manual-modal'),
|
||||||
|
{
|
||||||
|
onOpenStart: (modalElement, modalTriggerElement) => {
|
||||||
|
if ('manualModalChapter' in modalTriggerElement.dataset) {
|
||||||
|
let manualModalTocElement = document.querySelector('#manual-modal-toc');
|
||||||
|
let manualModalToc = M.Tabs.getInstance(manualModalTocElement);
|
||||||
|
manualModalToc.select(modalTriggerElement.dataset.manualModalChapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Terms of use modal
|
||||||
|
M.Modal.init(
|
||||||
|
document.querySelector('#terms-of-use-modal'),
|
||||||
|
{
|
||||||
|
dismissible: false,
|
||||||
|
onCloseEnd: (modalElement) => {
|
||||||
|
Requests.users.entity.acceptTermsOfUse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Nopaque Components
|
||||||
|
ResourceDisplays.AutoInit();
|
||||||
|
ResourceLists.AutoInit();
|
||||||
|
Forms.AutoInit();
|
||||||
|
// #endregion Nopaque Components
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
var Forms = {};
|
var Forms = {};
|
||||||
|
|
||||||
Forms.autoInit = () => {
|
Forms.AutoInit = () => {
|
||||||
for (let propertyName in Forms) {
|
for (let propertyName in Forms) {
|
||||||
let property = Forms[propertyName];
|
let property = Forms[propertyName];
|
||||||
// Call autoInit of all properties that are subclasses of Forms.BaseForm.
|
// Call autoInit of all properties that are subclasses of Forms.BaseForm.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
var ResourceDisplays = {};
|
var ResourceDisplays = {};
|
||||||
|
|
||||||
ResourceDisplays.autoInit = () => {
|
ResourceDisplays.AutoInit = () => {
|
||||||
for (let propertyName in ResourceDisplays) {
|
for (let propertyName in ResourceDisplays) {
|
||||||
let property = ResourceDisplays[propertyName];
|
let property = ResourceDisplays[propertyName];
|
||||||
// Call autoInit of all properties that are subclasses of `ResourceDisplays.ResourceDisplay`.
|
// Call autoInit of all properties that are subclasses of `ResourceDisplays.ResourceDisplay`.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
var ResourceLists = {};
|
var ResourceLists = {};
|
||||||
|
|
||||||
ResourceLists.autoInit = () => {
|
ResourceLists.AutoInit = () => {
|
||||||
for (let propertyName in ResourceLists) {
|
for (let propertyName in ResourceLists) {
|
||||||
let property = ResourceLists[propertyName];
|
let property = ResourceLists[propertyName];
|
||||||
// Call autoInit of all properties that are subclasses of `ResourceLists.ResourceList`.
|
// Call autoInit of all properties that are subclasses of `ResourceLists.ResourceList`.
|
||||||
|
@ -119,76 +119,29 @@
|
|||||||
<script>
|
<script>
|
||||||
// TODO: Implement an app.run method and use this for all of the following
|
// TODO: Implement an app.run method and use this for all of the following
|
||||||
const app = new App.App();
|
const app = new App.App();
|
||||||
|
app.init();
|
||||||
|
|
||||||
|
// Check if the current user is authenticated
|
||||||
{%- if current_user.is_authenticated %}
|
{%- if current_user.is_authenticated %}
|
||||||
|
// TODO: Set this as a property of the app object
|
||||||
const currentUserId = {{ current_user.hashid|tojson }};
|
const currentUserId = {{ current_user.hashid|tojson }};
|
||||||
|
|
||||||
// Initialize components for current user
|
// Subscribe to the current user's data events
|
||||||
app.subscribeUser(currentUserId)
|
app.subscribeUser(currentUserId)
|
||||||
.catch((error) => {throw JSON.stringify(error);});
|
.catch((error) => {throw JSON.stringify(error);});
|
||||||
|
|
||||||
|
// Get the current user's data
|
||||||
app.getUser(currentUserId, true, true)
|
app.getUser(currentUserId, true, true)
|
||||||
.catch((error) => {throw JSON.stringify(error);});
|
.catch((error) => {throw JSON.stringify(error);});
|
||||||
|
|
||||||
|
// Check if the current user hasn't accepted the terms of use yet
|
||||||
|
{%- if not current_user.terms_of_use_accepted %}
|
||||||
|
M.Modal.getInstance(document.querySelector('#terms-of-use-modal')).open();
|
||||||
|
{%- endif %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
// Disable all option elements with no value
|
|
||||||
for (let optionElement of document.querySelectorAll('option[value=""]')) {
|
|
||||||
optionElement.disabled = true;
|
|
||||||
}
|
|
||||||
for (let optgroupElement of document.querySelectorAll('optgroup[label=""]')) {
|
|
||||||
for (let c of optgroupElement.children) {
|
|
||||||
optgroupElement.parentElement.insertAdjacentElement('afterbegin', c);
|
|
||||||
}
|
|
||||||
optgroupElement.remove();
|
|
||||||
|
|
||||||
}
|
|
||||||
// Set the data-length attribute on textareas/inputs with the maxlength attribute
|
|
||||||
for (let inputElement of document.querySelectorAll('textarea[maxlength], input[maxlength]')) {
|
|
||||||
inputElement.dataset.length = inputElement.getAttribute('maxlength');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize components
|
|
||||||
M.AutoInit();
|
|
||||||
M.CharacterCounter.init(document.querySelectorAll('input[data-length], textarea[data-length]'));
|
|
||||||
M.Dropdown.init(
|
|
||||||
document.querySelectorAll('#nav-more-dropdown-trigger'),
|
|
||||||
{alignment: 'right', constrainWidth: false, coverTrigger: false}
|
|
||||||
);
|
|
||||||
ResourceDisplays.autoInit();
|
|
||||||
ResourceLists.autoInit();
|
|
||||||
Forms.autoInit();
|
|
||||||
|
|
||||||
// Display flashed messages
|
// Display flashed messages
|
||||||
for (let [category, message] of {{ get_flashed_messages(with_categories=True)|tojson }}) {
|
for (let [category, message] of {{ get_flashed_messages(with_categories=True)|tojson }}) {
|
||||||
app.flash(message, message);
|
app.flash(message, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize manual modal
|
|
||||||
let manualModalTableOfContentsElement = document.querySelector('#manual-modal-table-of-contents');
|
|
||||||
let manualModalTableOfContents = M.Tabs.init(manualModalTableOfContentsElement);
|
|
||||||
let manualModalElement = document.querySelector('#manual-modal');
|
|
||||||
let manualModal = M.Modal.init(
|
|
||||||
manualModalElement,
|
|
||||||
{
|
|
||||||
onOpenStart: (manualModalElement, modalTriggerElement) => {
|
|
||||||
if ('manualModalChapter' in modalTriggerElement.dataset) {
|
|
||||||
manualModalTableOfContents.select(modalTriggerElement.dataset.manualModalChapter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Initialize terms of use modal
|
|
||||||
const termsOfUseModal = document.getElementById('terms-of-use-modal');
|
|
||||||
M.Modal.init(
|
|
||||||
termsOfUseModal,
|
|
||||||
{
|
|
||||||
dismissible: false,
|
|
||||||
onCloseEnd: () => {
|
|
||||||
requests.users.entity.acceptTermsOfUse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
{% if current_user.is_authenticated and not current_user.terms_of_use_accepted %}
|
|
||||||
termsOfUseModal.M_Modal.open();
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<div id="manual-modal" class="modal no-autoinit">
|
<div id="manual-modal" class="modal no-autoinit">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<h2>Manual</h2>
|
<h2>Manual</h2>
|
||||||
<ul class="tabs no-autoinit" id="manual-modal-table-of-contents">
|
<ul class="tabs" id="manual-modal-toc">
|
||||||
<li class="tab"><a href="#manual-modal-introduction">Introduction</a></li>
|
<li class="tab"><a href="#manual-modal-introduction">Introduction</a></li>
|
||||||
<li class="tab"><a href="#manual-modal-registration-and-log-in">Registration and Log in</a></li>
|
<li class="tab"><a href="#manual-modal-registration-and-log-in">Registration and Log in</a></li>
|
||||||
<li class="tab"><a href="#manual-modal-dashboard">Dashboard</a></li>
|
<li class="tab"><a href="#manual-modal-dashboard">Dashboard</a></li>
|
||||||
|
Loading…
Reference in New Issue
Block a user