Address Javascript errors

This commit is contained in:
Max Berger
2026-03-08 00:30:25 +01:00
parent 93610213e3
commit 64885fe32e
6 changed files with 88 additions and 58 deletions

8
radicale/web/README.md Normal file
View File

@@ -0,0 +1,8 @@
# Built-in web UI
If you have tsc installed, you can type-check all JavaScript using
``` lang=shell
tsc -p radicale/web/jsconfig.json --noEmit --pretty
```

View File

@@ -42,17 +42,12 @@ export class CreateEditCollectionScene {
/** @type {HTMLElement} */ let title_form = edit ? html_scene.querySelector("[data-name=title]") : null;
/** @type {HTMLElement} */ let error_form = html_scene.querySelector("[data-name=error]");
/** @type {HTMLInputElement} */ let href_form = html_scene.querySelector("[data-name=href]");
/** @type {HTMLElement} */ let href_label = html_scene.querySelector("label[for=href]");
/** @type {HTMLInputElement} */ let displayname_form = html_scene.querySelector("[data-name=displayname]");
/** @type {HTMLElement} */ let displayname_label = html_scene.querySelector("label[for=displayname]");
/** @type {HTMLInputElement} */ let description_form = html_scene.querySelector("[data-name=description]");
/** @type {HTMLElement} */ let description_label = html_scene.querySelector("label[for=description]");
/** @type {HTMLInputElement} */ let source_form = html_scene.querySelector("[data-name=source]");
/** @type {HTMLElement} */ let source_label = html_scene.querySelector("label[for=source]");
/** @type {HTMLSelectElement} */ let type_form = html_scene.querySelector("[data-name=type]");
/** @type {HTMLElement} */ let type_label = html_scene.querySelector("label[for=type]");
/** @type {HTMLInputElement} */ let color_form = html_scene.querySelector("[data-name=color]");
/** @type {HTMLElement} */ let color_label = html_scene.querySelector("label[for=color]");
/** @type {HTMLElement} */ let submit_btn = html_scene.querySelector("[data-name=submit]");
/** @type {HTMLElement} */ let cancel_btn = html_scene.querySelector("[data-name=cancel]");
@@ -119,7 +114,7 @@ export class CreateEditCollectionScene {
error_form.classList.remove("hidden");
}
error_form.classList.add("hidden");
onTypeChange();
onTypeChange(null);
type_form.addEventListener("change", onTypeChange);
}
@@ -173,8 +168,10 @@ export class CreateEditCollectionScene {
return false;
}
function onTypeChange(e) {
/**
* @param {Event} _e
*/
function onTypeChange(_e) {
if (type_form.value == CollectionType.WEBCAL) {
source_label.classList.remove("hidden");
source_form.classList.remove("hidden");

View File

@@ -21,16 +21,17 @@
import { Scene } from "./scene_manager.js";
/**
* @constructor
* @implements {Scene}
*/
export function LoadingScene() {
let html_scene = document.getElementById("loadingscene");
this.show = function() {
html_scene.classList.remove("hidden");
};
this.hide = function() {
html_scene.classList.add("hidden");
};
this.release = function() {};
export class LoadingScene {
constructor() {
let html_scene = document.getElementById("loadingscene");
this.show = function () {
html_scene.classList.remove("hidden");
};
this.hide = function () {
html_scene.classList.add("hidden");
};
this.release = function () { };
}
}

View File

@@ -65,6 +65,7 @@ export function get_principal(user, password, callback) {
"",
"",
0,
0,
""), null);
} else {
callback(null, "Internal error");

View File

@@ -18,21 +18,32 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @enum {string}
*/
export const CollectionType = {
PRINCIPAL: "PRINCIPAL",
ADDRESSBOOK: "ADDRESSBOOK",
CALENDAR_JOURNAL_TASKS: "CALENDAR_JOURNAL_TASKS",
CALENDAR_JOURNAL: "CALENDAR_JOURNAL",
CALENDAR_TASKS: "CALENDAR_TASKS",
JOURNAL_TASKS: "JOURNAL_TASKS",
CALENDAR: "CALENDAR",
JOURNAL: "JOURNAL",
TASKS: "TASKS",
WEBCAL: "WEBCAL",
is_subset: function(a, b) {
export class CollectionType {
// Private Fields
static #_PRINCIPAL = "PRINCIPAL";
static #_ADDRESSBOOK = "ADDRESSBOOK";
static #_CALENDAR_JOURNAL_TASKS = "CALENDAR_JOURNAL_TASKS";
static #_CALENDAR_JOURNAL = "CALENDAR_JOURNAL";
static #_CALENDAR_TASKS = "CALENDAR_TASKS";
static #_JOURNAL_TASKS = "JOURNAL_TASKS";
static #_CALENDAR = "CALENDAR";
static #_JOURNAL = "JOURNAL";
static #_TASKS = "TASKS";
static #_WEBCAL = "WEBCAL";
// Accessors for "get" functions only (no "set" functions)
static get PRINCIPAL() { return this.#_PRINCIPAL; }
static get ADDRESSBOOK() { return this.#_ADDRESSBOOK; }
static get CALENDAR_JOURNAL_TASKS() { return this.#_CALENDAR_JOURNAL_TASKS; }
static get CALENDAR_JOURNAL() { return this.#_CALENDAR_JOURNAL; }
static get CALENDAR_TASKS() { return this.#_CALENDAR_TASKS; }
static get JOURNAL_TASKS() { return this.#_JOURNAL_TASKS; }
static get CALENDAR() { return this.#_CALENDAR; }
static get JOURNAL() { return this.#_JOURNAL; }
static get TASKS() { return this.#_TASKS; }
static get WEBCAL() { return this.#_WEBCAL; }
static is_subset(/** @type {string} */ a, /** @type {string} */ b) {
let components = a.split("_");
for (let i = 0; i < components.length; i++) {
if (b.search(components[i]) === -1) {
@@ -40,8 +51,9 @@ export const CollectionType = {
}
}
return true;
},
union: function(a, b) {
}
static union(/** @type {string} */ a, /** @type {string} */ b) {
if (a.search(this.ADDRESSBOOK) !== -1 || b.search(this.ADDRESSBOOK) !== -1) {
if (a && a !== this.ADDRESSBOOK || b && b !== this.ADDRESSBOOK) {
throw "Invalid union: " + a + " " + b;
@@ -62,10 +74,14 @@ export const CollectionType = {
union.push(this.WEBCAL);
}
return union.join("_");
},
valid_options_for_type: function(a){
}
/**
* @param {string} a
*/
static valid_options_for_type(a) {
a = a.trim().toUpperCase();
switch(a){
switch (a) {
case CollectionType.CALENDAR_JOURNAL_TASKS:
case CollectionType.CALENDAR_JOURNAL:
case CollectionType.CALENDAR_TASKS:
@@ -80,24 +96,28 @@ export const CollectionType = {
return [a];
}
}
};
}
/**
* @constructor
* @struct
* @param {string} href Must always start and end with /.
* @param {CollectionType} type
* @param {string} displayname
* @param {string} description
* @param {string} color
*/
export function Collection(href, type, displayname, description, color, contentcount, size, source) {
this.href = href;
this.type = type;
this.displayname = displayname;
this.color = color;
this.description = description;
this.source = source;
this.contentcount = contentcount;
this.size = size;
export class Collection {
/**
* @param {string} href Must always start and end with /.
* @param {string} type
* @param {string} displayname
* @param {string} description
* @param {string} color
* @param {number} contentcount
* @param {number} size
* @param {string} source
*/
constructor(href, type, displayname, description, color, contentcount, size, source) {
this.href = href;
this.type = type;
this.displayname = displayname;
this.color = color;
this.description = description;
this.source = source;
this.contentcount = contentcount;
this.size = size;
}
}

View File

@@ -2,7 +2,10 @@
"compilerOptions": {
"module": "CommonJS",
"target": "ES6",
"checkJs": true
"checkJs": true,
"noEmit": true,
"noUnusedLocals": true,
"noUnusedParameters": true
},
"include": [
"internal_data/**/*.js"