diff --git a/radicale/web/internal_data/CollectionsScene.js b/radicale/web/internal_data/CollectionsScene.js index 2c8b05fa..b1b56ba7 100644 --- a/radicale/web/internal_data/CollectionsScene.js +++ b/radicale/web/internal_data/CollectionsScene.js @@ -18,16 +18,16 @@ * along with this program. If not, see . */ -import { Scene, push_scene, pop_scene, scene_stack } from "./scene_manager.js"; import { CreateEditCollectionScene } from "./CreateEditCollectionScene.js"; -import { CreateShareCollectionScene } from "./ShareCollectionScene.js"; -import { UploadCollectionScene } from "./UploadCollectionScene.js"; import { DeleteCollectionScene } from "./DeleteCollectionScene.js"; import { LoadingScene } from "./LoadingScene.js"; +import { CreateShareCollectionScene } from "./ShareCollectionScene.js"; +import { UploadCollectionScene } from "./UploadCollectionScene.js"; import { get_collections } from "./api.js"; -import { CollectionType } from "./models.js"; -import { bytesToHumanReadable } from "./utils.js"; import { SERVER } from "./constants.js"; +import { Collection, CollectionType } from "./models.js"; +import { Scene, pop_scene, push_scene, scene_stack } from "./scene_manager.js"; +import { bytesToHumanReadable } from "./utils.js"; /** * @constructor @@ -35,181 +35,184 @@ import { SERVER } from "./constants.js"; * @param {string} user * @param {string} password * @param {Collection} collection The principal collection. - * @param {function(string)} onerror Called when an error occurs, before the + * @param {function(string):void} onerror Called when an error occurs, before the * scene is popped. */ -export function CollectionsScene(user, password, collection, onerror) { - let html_scene = document.getElementById("collectionsscene"); - let template = html_scene.querySelector("[data-name=collectiontemplate]"); - let new_btn = html_scene.querySelector("[data-name=new]"); - let upload_btn = html_scene.querySelector("[data-name=upload]"); +export class CollectionsScene { + constructor(user, password, collection, onerror) { + /** @type {HTMLElement} */ let html_scene = document.getElementById("collectionsscene"); + /** @type {HTMLElement} */ let template = html_scene.querySelector("[data-name=collectiontemplate]"); + /** @type {HTMLElement} */ let new_btn = html_scene.querySelector("[data-name=new]"); + /** @type {HTMLElement} */ let upload_btn = html_scene.querySelector("[data-name=upload]"); - /** @type {?number} */ let scene_index = null; - /** @type {?XMLHttpRequest} */ let collections_req = null; - /** @type {?Array} */ let collections = null; - /** @type {Array} */ let nodes = []; + /** @type {?number} */ let scene_index = null; + /** @type {?XMLHttpRequest} */ let collections_req = null; + /** @type {?Array} */ let collections = null; + /** @type {Array} */ let nodes = []; - function onnew() { - try { - let create_collection_scene = new CreateEditCollectionScene(user, password, collection); - push_scene(create_collection_scene, false); - } catch(err) { - console.error(err); - } - return false; - } - - function onupload() { - try { - let upload_scene = new UploadCollectionScene(user, password, collection); - push_scene(upload_scene); - } catch(err) { - console.error(err); - } - return false; - } - - function onedit(collection) { - try { - let edit_collection_scene = new CreateEditCollectionScene(user, password, collection); - push_scene(edit_collection_scene, false); - } catch(err) { - console.error(err); - } - return false; - } - - function onshare(collection) { - try { - let share_collection_scene = new CreateShareCollectionScene(user, password, collection); - push_scene(share_collection_scene, false); - } catch(err) { - console.error(err); - } - return false; - } - - function ondelete(collection) { - try { - let delete_collection_scene = new DeleteCollectionScene(user, password, collection); - push_scene(delete_collection_scene, false); - } catch(err) { - console.error(err); - } - return false; - } - - function show_collections(collections) { - let heightOfNavBar = document.querySelector("#logoutview").offsetHeight + "px"; - html_scene.style.marginTop = heightOfNavBar; - html_scene.style.height = "calc(100vh - " + heightOfNavBar +")"; - collections.forEach(function (collection) { - let node = template.cloneNode(true); - node.classList.remove("hidden"); - let title_form = node.querySelector("[data-name=title]"); - let description_form = node.querySelector("[data-name=description]"); - let contentcount_form = node.querySelector("[data-name=contentcount]"); - let url_form = node.querySelector("[data-name=url]"); - let color_form = node.querySelector("[data-name=color]"); - let delete_btn = node.querySelector("[data-name=delete]"); - let edit_btn = node.querySelector("[data-name=edit]"); - let share_btn = node.querySelector("[data-name=share]"); - let download_btn = node.querySelector("[data-name=download]"); - if (collection.color) { - color_form.style.background = collection.color; + function onnew() { + try { + let create_collection_scene = new CreateEditCollectionScene(user, password, collection); + push_scene(create_collection_scene, false); + } catch (err) { + console.error(err); } - let possible_types = [CollectionType.ADDRESSBOOK, CollectionType.WEBCAL]; - [CollectionType.CALENDAR, ""].forEach(function(e) { - [CollectionType.union(e, CollectionType.JOURNAL), e].forEach(function(e) { - [CollectionType.union(e, CollectionType.TASKS), e].forEach(function(e) { - if (e) { - possible_types.push(e); - } + return false; + } + + function onupload() { + try { + let upload_scene = new UploadCollectionScene(user, password, collection); + push_scene(upload_scene, false); + } catch (err) { + console.error(err); + } + return false; + } + + function onedit(collection) { + try { + let edit_collection_scene = new CreateEditCollectionScene(user, password, collection); + push_scene(edit_collection_scene, false); + } catch (err) { + console.error(err); + } + return false; + } + + function onshare(collection) { + try { + let share_collection_scene = new CreateShareCollectionScene(user, password, collection); + push_scene(share_collection_scene, false); + } catch (err) { + console.error(err); + } + return false; + } + + function ondelete(collection) { + try { + let delete_collection_scene = new DeleteCollectionScene(user, password, collection); + push_scene(delete_collection_scene, false); + } catch (err) { + console.error(err); + } + return false; + } + + function show_collections(collections) { + /** @type {HTMLElement} */ let navBar = document.querySelector("#logoutview"); + let heightOfNavBar = navBar.offsetHeight + "px"; + html_scene.style.marginTop = heightOfNavBar; + html_scene.style.height = "calc(100vh - " + heightOfNavBar + ")"; + collections.forEach(function (collection) { + /** @type {HTMLElement} */ let node = /** @type {HTMLElement} */(template.cloneNode(true)); + node.classList.remove("hidden"); + /** @type {HTMLElement} */ let title_form = node.querySelector("[data-name=title]"); + /** @type {HTMLElement} */ let description_form = node.querySelector("[data-name=description]"); + /** @type {HTMLElement} */ let contentcount_form = node.querySelector("[data-name=contentcount]"); + /** @type {HTMLInputElement} */ let url_form = node.querySelector("[data-name=url]"); + /** @type {HTMLElement} */ let color_form = node.querySelector("[data-name=color]"); + /** @type {HTMLElement} */ let delete_btn = node.querySelector("[data-name=delete]"); + /** @type {HTMLElement} */ let edit_btn = node.querySelector("[data-name=edit]"); + /** @type {HTMLElement} */ let share_btn = node.querySelector("[data-name=share]"); + /** @type {HTMLAnchorElement} */ let download_btn = node.querySelector("[data-name=download]"); + if (collection.color) { + color_form.style.background = collection.color; + } + let possible_types = [CollectionType.ADDRESSBOOK, CollectionType.WEBCAL]; + [CollectionType.CALENDAR, ""].forEach(function (e) { + [CollectionType.union(e, CollectionType.JOURNAL), e].forEach(function (e) { + [CollectionType.union(e, CollectionType.TASKS), e].forEach(function (e) { + if (e) { + possible_types.push(e); + } + }); }); }); - }); - possible_types.forEach(function(e) { - if (e !== collection.type) { - node.querySelector("[data-name=" + e + "]").classList.add("hidden"); + possible_types.forEach(function (e) { + if (e !== collection.type) { + node.querySelector("[data-name=" + e + "]").classList.add("hidden"); + } + }); + title_form.textContent = collection.displayname || collection.href; + if (title_form.textContent.length > 30) { + title_form.classList.add("smalltext"); } - }); - title_form.textContent = collection.displayname || collection.href; - if(title_form.textContent.length > 30){ - title_form.classList.add("smalltext"); - } - description_form.textContent = collection.description; - if(description_form.textContent.length > 150){ - description_form.classList.add("smalltext"); - } - if(collection.type != CollectionType.WEBCAL){ - let contentcount_form_txt = (collection.contentcount > 0 ? Number(collection.contentcount).toLocaleString() : "No") + " item" + (collection.contentcount == 1 ? "" : "s") + " in collection"; - if(collection.contentcount > 0){ - contentcount_form_txt += " (" + bytesToHumanReadable(collection.size) + ")"; + description_form.textContent = collection.description; + if (description_form.textContent.length > 150) { + description_form.classList.add("smalltext"); } - contentcount_form.textContent = contentcount_form_txt; - } - let href = SERVER + collection.href; - url_form.value = href; - download_btn.href = href; - if(collection.type == CollectionType.WEBCAL){ - download_btn.parentElement.classList.add("hidden"); - } - delete_btn.onclick = function() {return ondelete(collection);}; - edit_btn.onclick = function() {return onedit(collection);}; - share_btn.onclick = function() {return onshare(collection);}; - node.classList.remove("hidden"); - nodes.push(node); - template.parentNode.insertBefore(node, template); - }); - } + if (collection.type != CollectionType.WEBCAL) { + let contentcount_form_txt = (collection.contentcount > 0 ? Number(collection.contentcount).toLocaleString() : "No") + " item" + (collection.contentcount == 1 ? "" : "s") + " in collection"; + if (collection.contentcount > 0) { + contentcount_form_txt += " (" + bytesToHumanReadable(collection.size) + ")"; + } + contentcount_form.textContent = contentcount_form_txt; + } + let href = SERVER + collection.href; + url_form.value = href; + download_btn.href = href; + if (collection.type == CollectionType.WEBCAL) { + download_btn.parentElement.classList.add("hidden"); + } + delete_btn.onclick = function () { return ondelete(collection); }; + edit_btn.onclick = function () { return onedit(collection); }; + share_btn.onclick = function () { return onshare(collection); }; + node.classList.remove("hidden"); + nodes.push(node); + template.parentNode.insertBefore(node, template); + }); + } - function update() { - let loading_scene = new LoadingScene(); - push_scene(loading_scene, false); - collections_req = get_collections(user, password, collection, function(collections1, error) { - if (scene_index === null) { - return; - } - collections_req = null; - if (error) { - onerror(error); - pop_scene(scene_index - 1); + function update() { + let loading_scene = new LoadingScene(); + push_scene(loading_scene, false); + collections_req = get_collections(user, password, collection, function (collections1, error) { + if (scene_index === null) { + return; + } + collections_req = null; + if (error) { + onerror(error); + pop_scene(scene_index - 1); + } else { + collections = collections1; + pop_scene(scene_index); + } + }); + } + + this.show = function () { + html_scene.classList.remove("hidden"); + new_btn.onclick = onnew; + upload_btn.onclick = onupload; + if (collections === null) { + update(); } else { - collections = collections1; - pop_scene(scene_index); + // from update loading scene + show_collections(collections); } - }); + }; + this.hide = function () { + html_scene.classList.add("hidden"); + scene_index = scene_stack.length - 1; + new_btn.onclick = null; + upload_btn.onclick = null; + collections = null; + // remove collection + nodes.forEach(function (node) { + node.parentNode.removeChild(node); + }); + nodes = []; + }; + this.release = function () { + scene_index = null; + if (collections_req !== null) { + collections_req.abort(); + collections_req = null; + } + collections = null; + }; } - - this.show = function() { - html_scene.classList.remove("hidden"); - new_btn.onclick = onnew; - upload_btn.onclick = onupload; - if (collections === null) { - update(); - } else { - // from update loading scene - show_collections(collections); - } - }; - this.hide = function() { - html_scene.classList.add("hidden"); - scene_index = scene_stack.length - 1; - new_btn.onclick = null; - upload_btn.onclick = null; - collections = null; - // remove collection - nodes.forEach(function(node) { - node.parentNode.removeChild(node); - }); - nodes = []; - }; - this.release = function() { - scene_index = null; - if (collections_req !== null) { - collections_req.abort(); - collections_req = null; - } - collections = null; - }; } \ No newline at end of file diff --git a/radicale/web/internal_data/CreateEditCollectionScene.js b/radicale/web/internal_data/CreateEditCollectionScene.js index 94791246..49982734 100644 --- a/radicale/web/internal_data/CreateEditCollectionScene.js +++ b/radicale/web/internal_data/CreateEditCollectionScene.js @@ -37,28 +37,28 @@ import { create_collection, edit_collection } from "./api.js"; export function CreateEditCollectionScene(user, password, collection) { let edit = collection.type !== CollectionType.PRINCIPAL; let html_scene = document.getElementById(edit ? "editcollectionscene" : "createcollectionscene"); - let title_form = edit ? html_scene.querySelector("[data-name=title]") : null; - let error_form = html_scene.querySelector("[data-name=error]"); - let href_form = html_scene.querySelector("[data-name=href]"); - let href_label = html_scene.querySelector("label[for=href]"); - let displayname_form = html_scene.querySelector("[data-name=displayname]"); - let displayname_label = html_scene.querySelector("label[for=displayname]"); - let description_form = html_scene.querySelector("[data-name=description]"); - let description_label = html_scene.querySelector("label[for=description]"); - let source_form = html_scene.querySelector("[data-name=source]"); - let source_label = html_scene.querySelector("label[for=source]"); - let type_form = html_scene.querySelector("[data-name=type]"); - let type_label = html_scene.querySelector("label[for=type]"); - let color_form = html_scene.querySelector("[data-name=color]"); - let color_label = html_scene.querySelector("label[for=color]"); - let submit_btn = html_scene.querySelector("[data-name=submit]"); - let cancel_btn = html_scene.querySelector("[data-name=cancel]"); + /** @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]"); /** @type {?number} */ let scene_index = null; /** @type {?XMLHttpRequest} */ let create_edit_req = null; let error = ""; - /** @type {?Element} */ let saved_type_form = null; + /** @type {?HTMLSelectElement} */ let saved_type_form = null; let href = edit ? collection.href : collection.href + random_uuid() + "/"; let displayname = edit ? collection.displayname : ""; @@ -137,7 +137,7 @@ export function CreateEditCollectionScene(user, password, collection) { sane_color = color_match[1]; } let loading_scene = new LoadingScene(); - push_scene(loading_scene); + push_scene(loading_scene, false); let collection = new Collection(href, type, displayname, description, sane_color, 0, 0, source); let callback = function(error1) { if (scene_index === null) { diff --git a/radicale/web/internal_data/DeleteCollectionScene.js b/radicale/web/internal_data/DeleteCollectionScene.js index fd1f9d98..c7cc1c93 100644 --- a/radicale/web/internal_data/DeleteCollectionScene.js +++ b/radicale/web/internal_data/DeleteCollectionScene.js @@ -32,13 +32,13 @@ import { delete_collection } from "./api.js"; * @param {Collection} collection */ export function DeleteCollectionScene(user, password, collection) { - let html_scene = document.getElementById("deletecollectionscene"); - let title_form = html_scene.querySelector("[data-name=title]"); - let error_form = html_scene.querySelector("[data-name=error]"); - let confirmation_txt = html_scene.querySelector("[data-name=confirmationtxt]"); - let delete_confirmation_lbl = html_scene.querySelector("[data-name=deleteconfirmationtext]"); - let delete_btn = html_scene.querySelector("[data-name=delete]"); - let cancel_btn = html_scene.querySelector("[data-name=cancel]"); + /** @type {HTMLElement} */ let html_scene = document.getElementById("deletecollectionscene"); + /** @type {HTMLElement} */ let title_form = html_scene.querySelector("[data-name=title]"); + /** @type {HTMLElement} */ let error_form = html_scene.querySelector("[data-name=error]"); + /** @type {HTMLInputElement} */ let confirmation_txt = html_scene.querySelector("[data-name=confirmationtxt]"); + /** @type {HTMLElement} */ let delete_confirmation_lbl = html_scene.querySelector("[data-name=deleteconfirmationtext]"); + /** @type {HTMLElement} */ let delete_btn = html_scene.querySelector("[data-name=delete]"); + /** @type {HTMLElement} */ let cancel_btn = html_scene.querySelector("[data-name=cancel]"); delete_confirmation_lbl.innerHTML = DELETE_CONFIRMATION_TEXT; confirmation_txt.value = ""; @@ -56,7 +56,7 @@ export function DeleteCollectionScene(user, password, collection) { } try { let loading_scene = new LoadingScene(); - push_scene(loading_scene); + push_scene(loading_scene, false); delete_req = delete_collection(user, password, collection, function(error1) { if (scene_index === null) { return; diff --git a/radicale/web/internal_data/LoginScene.js b/radicale/web/internal_data/LoginScene.js index 63c68f2f..b6f1a68e 100644 --- a/radicale/web/internal_data/LoginScene.js +++ b/radicale/web/internal_data/LoginScene.js @@ -29,15 +29,15 @@ import { maybe_enable_sharing_options } from "./ShareCollectionScene.js"; * @implements {Scene} */ export function LoginScene() { - let html_scene = document.getElementById("loginscene"); - let form = html_scene.querySelector("[data-name=form]"); - let user_form = html_scene.querySelector("[data-name=user]"); - let password_form = html_scene.querySelector("[data-name=password]"); - let error_form = html_scene.querySelector("[data-name=error]"); - let logout_view = document.getElementById("logoutview"); - let logout_user_form = logout_view.querySelector("[data-name=user]"); - let logout_btn = logout_view.querySelector("[data-name=logout]"); - let refresh_btn = logout_view.querySelector("[data-name=refresh]"); + /** @type {HTMLElement} */ let html_scene = document.getElementById("loginscene"); + /** @type {HTMLElement} */ let form = html_scene.querySelector("[data-name=form]"); + /** @type {HTMLInputElement} */ let user_form = html_scene.querySelector("[data-name=user]"); + /** @type {HTMLInputElement} */ let password_form = html_scene.querySelector("[data-name=password]"); + /** @type {HTMLElement} */ let error_form = html_scene.querySelector("[data-name=error]"); + /** @type {HTMLElement} */ let logout_view = document.getElementById("logoutview"); + /** @type {HTMLElement} */ let logout_user_form = logout_view.querySelector("[data-name=user]"); + /** @type {HTMLElement} */ let logout_btn = logout_view.querySelector("[data-name=logout]"); + /** @type {HTMLElement} */ let refresh_btn = logout_view.querySelector("[data-name=refresh]"); /** @type {?number} */ let scene_index = null; let user = ""; diff --git a/radicale/web/internal_data/ShareCollectionScene.js b/radicale/web/internal_data/ShareCollectionScene.js index 37a830bf..1a610a29 100644 --- a/radicale/web/internal_data/ShareCollectionScene.js +++ b/radicale/web/internal_data/ShareCollectionScene.js @@ -24,7 +24,8 @@ import { reload_sharing_list, server_features, } from "./api.js"; -import { pop_scene, scene_stack } from "./scene_manager.js"; +import { Collection } from "./models.js"; +import { Scene, pop_scene, scene_stack } from "./scene_manager.js"; /** * @constructor @@ -33,64 +34,73 @@ import { pop_scene, scene_stack } from "./scene_manager.js"; * @param {string} password * @param {Collection} collection The collection on which to edit sharing setting. Must exist. */ -export function CreateShareCollectionScene(user, password, collection) { - /** @type {?number} */ let scene_index = null; +/** + * @constructor + * @implements {Scene} + * @param {string} user + * @param {string} password + * @param {Collection} collection The collection on which to edit sharing setting. Must exist. + */ +export class CreateShareCollectionScene { + constructor(user, password, collection) { + /** @type {?number} */ let scene_index = null; - let html_scene = document.getElementById("sharecollectionscene"); + let html_scene = document.getElementById("sharecollectionscene"); - let cancel_btn = html_scene.querySelector("[data-name=cancel]"); - let share_by_token_btn_ro = html_scene.querySelector( - "[data-name=sharebytoken_ro]", - ); - let share_by_token_btn_rw = html_scene.querySelector( - "[data-name=sharebytoken_rw]", - ); + /** @type {HTMLElement} */ let cancel_btn = html_scene.querySelector("[data-name=cancel]"); + /** @type {HTMLElement} */ let share_by_token_btn_ro = html_scene.querySelector( + "[data-name=sharebytoken_ro]" + ); + /** @type {HTMLElement} */ let share_by_token_btn_rw = html_scene.querySelector( + "[data-name=sharebytoken_rw]" + ); - let title = html_scene.querySelector("[data-name=title]"); + /** @type {HTMLElement} */ let title = html_scene.querySelector("[data-name=title]"); - function oncancel() { - try { - pop_scene(scene_index - 1); - } catch (err) { - console.error(err); + function oncancel() { + try { + pop_scene(scene_index - 1); + } catch (err) { + console.error(err); + } + return false; } - return false; - } - function onsharebytoken_rw() { - add_share_by_token(user, password, collection, "rw", function () { - update_share_list(user, password, collection); - }); - } - - function onsharebytoken_ro() { - add_share_by_token(user, password, collection, "r", function () { - update_share_list(user, password, collection); - }); - } - - this.show = function () { - this.release(); - scene_index = scene_stack.length - 1; - html_scene.classList.remove("hidden"); - cancel_btn.onclick = oncancel; - if (server_features["sharing"]["FeatureEnabledCollectionByToken"]) { - share_by_token_btn_ro.onclick = onsharebytoken_ro; - share_by_token_btn_rw.onclick = onsharebytoken_rw; - } else { - share_by_token_btn_ro.parentElement.removeChild(share_by_token_btn_ro); - share_by_token_btn_rw.parentElement.removeChild(share_by_token_btn_rw); + function onsharebytoken_rw() { + add_share_by_token(user, password, collection, "rw", function () { + update_share_list(user, password, collection); + }); } - title.textContent = collection.displayname || collection.href; - update_share_list(user, password, collection); - }; - this.hide = function () { - html_scene.classList.add("hidden"); - cancel_btn.onclick = null; - }; - this.release = function () { - scene_index = null; - }; + + function onsharebytoken_ro() { + add_share_by_token(user, password, collection, "r", function () { + update_share_list(user, password, collection); + }); + } + + this.show = function () { + this.release(); + scene_index = scene_stack.length - 1; + html_scene.classList.remove("hidden"); + cancel_btn.onclick = oncancel; + if (server_features["sharing"]["FeatureEnabledCollectionByToken"]) { + share_by_token_btn_ro.onclick = onsharebytoken_ro; + share_by_token_btn_rw.onclick = onsharebytoken_rw; + } else { + share_by_token_btn_ro.parentElement.removeChild(share_by_token_btn_ro); + share_by_token_btn_rw.parentElement.removeChild(share_by_token_btn_rw); + } + title.textContent = collection.displayname || collection.href; + update_share_list(user, password, collection); + }; + this.hide = function () { + html_scene.classList.add("hidden"); + cancel_btn.onclick = null; + }; + this.release = function () { + scene_index = null; + }; + } } function update_share_list(user, password, collection) { @@ -109,7 +119,7 @@ function update_share_list(user, password, collection) { } function add_share_rows(user, password, collection, shares) { - let template = document.querySelector("[data-name=sharetokenrowtemplate]"); + /** @type {HTMLElement} */ let template = document.querySelector("[data-name=sharetokenrowtemplate]"); shares.forEach(function (share) { let pathortoken = share["PathOrToken"] || ""; let pathmapped = share["PathMapped"] || ""; @@ -117,9 +127,10 @@ function add_share_rows(user, password, collection, shares) { collection.href.includes(pathmapped) || collection.href.includes(pathortoken) ) { - let node = template.cloneNode(true); + let node = /** @type {HTMLElement} */ (template.cloneNode(true)); node.classList.remove("hidden"); - node.querySelector("[data-name=pathortoken]").value = pathortoken; + /** @type {HTMLInputElement} */ let pathortoken_form = node.querySelector("[data-name=pathortoken]"); + pathortoken_form.value = pathortoken; let permissions = (share["Permissions"] || "").toLowerCase(); if (permissions === "rw") { node @@ -132,7 +143,8 @@ function add_share_rows(user, password, collection, shares) { } else { console.warn("Unknown permissions", permissions); } - node.querySelector("[data-name=delete]").onclick = function () { + /** @type {HTMLElement} */ let delete_btn = node.querySelector("[data-name=delete]"); + delete_btn.onclick = function () { delete_share_by_token( user, password, diff --git a/radicale/web/internal_data/UploadCollectionScene.js b/radicale/web/internal_data/UploadCollectionScene.js index fbc5b29f..2704f461 100644 --- a/radicale/web/internal_data/UploadCollectionScene.js +++ b/radicale/web/internal_data/UploadCollectionScene.js @@ -29,19 +29,18 @@ import { upload_collection } from "./api.js"; * @param {string} user * @param {string} password * @param {Collection} collection parent collection - * @param {Array} files */ export function UploadCollectionScene(user, password, collection) { - let html_scene = document.getElementById("uploadcollectionscene"); - let template = html_scene.querySelector("[data-name=filetemplate]"); - let upload_btn = html_scene.querySelector("[data-name=submit]"); - let close_btn = html_scene.querySelector("[data-name=close]"); - let uploadfile_form = html_scene.querySelector("[data-name=uploadfile]"); - let uploadfile_lbl = html_scene.querySelector("label[for=uploadfile]"); - let href_form = html_scene.querySelector("[data-name=href]"); - let href_label = html_scene.querySelector("label[for=href]"); - let hreflimitmsg_html = html_scene.querySelector("[data-name=hreflimitmsg]"); - let pending_html = html_scene.querySelector("[data-name=pending]"); + /** @type {HTMLElement} */ let html_scene = document.getElementById("uploadcollectionscene"); + /** @type {HTMLElement} */ let template = html_scene.querySelector("[data-name=filetemplate]"); + /** @type {HTMLElement} */ let upload_btn = html_scene.querySelector("[data-name=submit]"); + /** @type {HTMLElement} */ let close_btn = html_scene.querySelector("[data-name=close]"); + /** @type {HTMLInputElement} */ let uploadfile_form = html_scene.querySelector("[data-name=uploadfile]"); + /** @type {HTMLElement} */ let uploadfile_lbl = html_scene.querySelector("label[for=uploadfile]"); + /** @type {HTMLInputElement} */ let href_form = html_scene.querySelector("[data-name=href]"); + /** @type {HTMLElement} */ let href_label = html_scene.querySelector("label[for=href]"); + /** @type {HTMLElement} */ let hreflimitmsg_html = html_scene.querySelector("[data-name=hreflimitmsg]"); + /** @type {HTMLElement} */ let pending_html = html_scene.querySelector("[data-name=pending]"); let files = uploadfile_form.files; href_form.addEventListener("keydown", cleanHREFinput); @@ -49,11 +48,12 @@ export function UploadCollectionScene(user, password, collection) { uploadfile_form.onchange = onfileschange; href_form.value = ""; + let href = ""; /** @type {?number} */ let scene_index = null; /** @type {?XMLHttpRequest} */ let upload_req = null; /** @type {Array} */ let results = []; - /** @type {?Array} */ let nodes = null; + /** @type {?Array} */ let nodes = null; function upload_start() { try { @@ -73,7 +73,7 @@ export function UploadCollectionScene(user, password, collection) { nodes = []; for (let i = 0; i < files.length; i++) { let file = files[i]; - let node = template.cloneNode(true); + /** @type {HTMLElement} */ let node = template.cloneNode(true); node.classList.remove("hidden"); let name_form = node.querySelector("[data-name=name]"); name_form.textContent = file.name; @@ -180,12 +180,6 @@ export function UploadCollectionScene(user, password, collection) { scene_index = scene_stack.length - 1; html_scene.classList.remove("hidden"); close_btn.onclick = onclose; - if(error){ - error_form.textContent = "Error: " + error; - error_form.classList.remove("hidden"); - }else{ - error_form.classList.add("hidden"); - } }; this.hide = function() { diff --git a/radicale/web/internal_data/scene_manager.js b/radicale/web/internal_data/scene_manager.js index bb489257..2f4b416c 100644 --- a/radicale/web/internal_data/scene_manager.js +++ b/radicale/web/internal_data/scene_manager.js @@ -21,19 +21,21 @@ /** * @interface */ -export function Scene() {} -/** - * Scene is on top of stack and visible. - */ -Scene.prototype.show = function() {}; -/** - * Scene is no longer visible. - */ -Scene.prototype.hide = function() {}; -/** - * Scene is removed from scene stack. - */ -Scene.prototype.release = function() {}; +export class Scene { + constructor() { } + /** + * Scene is on top of stack and visible. + */ + show() { } + /** + * Scene is no longer visible. + */ + hide() { } + /** + * Scene is removed from scene stack. + */ + release() { } +} /** diff --git a/radicale/web/jsconfig.json b/radicale/web/jsconfig.json new file mode 100644 index 00000000..06467fa5 --- /dev/null +++ b/radicale/web/jsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "CommonJS", + "target": "ES6", + "checkJs": true + }, + "include": [ + "internal_data/**/*.js" + ] +} \ No newline at end of file