]> source.dussan.org Git - gitea.git/commitdiff
Fix a number of typescript issues (#32459)
authorsilverwind <me@silverwind.io>
Mon, 11 Nov 2024 11:13:57 +0000 (12:13 +0100)
committerGitHub <noreply@github.com>
Mon, 11 Nov 2024 11:13:57 +0000 (11:13 +0000)
Fixes 69 typescript errors found in the `admin` and `markup` folders.

---------

Co-authored-by: Giteabot <teabot@gitea.io>
14 files changed:
web_src/js/features/admin/common.ts
web_src/js/features/admin/config.ts
web_src/js/features/admin/emails.ts
web_src/js/features/admin/selfcheck.ts
web_src/js/features/admin/users.ts
web_src/js/markup/anchors.ts
web_src/js/markup/codecopy.ts
web_src/js/markup/common.ts
web_src/js/markup/content.ts
web_src/js/markup/html2markdown.ts
web_src/js/markup/math.ts
web_src/js/markup/mermaid.ts
web_src/js/markup/tasklist.ts
web_src/js/svg.ts

index 934a30a3ee9e506f3d1e9d1c0de7d87aba7a7003..6c725a3efe4c2d1f01fc99aabf6eac31a2a4b236 100644 (file)
@@ -5,15 +5,15 @@ import {POST} from '../../modules/fetch.ts';
 
 const {appSubUrl} = window.config;
 
-function onSecurityProtocolChange() {
-  if (Number(document.querySelector('#security_protocol')?.value) > 0) {
+function onSecurityProtocolChange(): void {
+  if (Number(document.querySelector<HTMLInputElement>('#security_protocol')?.value) > 0) {
     showElem('.has-tls');
   } else {
     hideElem('.has-tls');
   }
 }
 
-export function initAdminCommon() {
+export function initAdminCommon(): void {
   if (!document.querySelector('.page-content.admin')) return;
 
   // check whether appUrl(ROOT_URL) is correct, if not, show an error message
@@ -21,34 +21,34 @@ export function initAdminCommon() {
 
   // New user
   if ($('.admin.new.user').length > 0 || $('.admin.edit.user').length > 0) {
-    document.querySelector('#login_type')?.addEventListener('change', function () {
-      if (this.value?.substring(0, 1) === '0') {
-        document.querySelector('#user_name')?.removeAttribute('disabled');
-        document.querySelector('#login_name')?.removeAttribute('required');
+    document.querySelector<HTMLInputElement>('#login_type')?.addEventListener('change', function () {
+      if (this.value?.startsWith('0')) {
+        document.querySelector<HTMLInputElement>('#user_name')?.removeAttribute('disabled');
+        document.querySelector<HTMLInputElement>('#login_name')?.removeAttribute('required');
         hideElem('.non-local');
         showElem('.local');
-        document.querySelector('#user_name')?.focus();
+        document.querySelector<HTMLInputElement>('#user_name')?.focus();
 
         if (this.getAttribute('data-password') === 'required') {
           document.querySelector('#password')?.setAttribute('required', 'required');
         }
       } else {
-        if (document.querySelector('.admin.edit.user')) {
-          document.querySelector('#user_name')?.setAttribute('disabled', 'disabled');
+        if (document.querySelector<HTMLDivElement>('.admin.edit.user')) {
+          document.querySelector<HTMLInputElement>('#user_name')?.setAttribute('disabled', 'disabled');
         }
-        document.querySelector('#login_name')?.setAttribute('required', 'required');
+        document.querySelector<HTMLInputElement>('#login_name')?.setAttribute('required', 'required');
         showElem('.non-local');
         hideElem('.local');
-        document.querySelector('#login_name')?.focus();
+        document.querySelector<HTMLInputElement>('#login_name')?.focus();
 
-        document.querySelector('#password')?.removeAttribute('required');
+        document.querySelector<HTMLInputElement>('#password')?.removeAttribute('required');
       }
     });
   }
 
   function onUsePagedSearchChange() {
-    const searchPageSizeElements = document.querySelectorAll('.search-page-size');
-    if (document.querySelector('#use_paged_search').checked) {
+    const searchPageSizeElements = document.querySelectorAll<HTMLDivElement>('.search-page-size');
+    if (document.querySelector<HTMLInputElement>('#use_paged_search').checked) {
       showElem('.search-page-size');
       for (const el of searchPageSizeElements) {
         el.querySelector('input')?.setAttribute('required', 'required');
@@ -61,20 +61,20 @@ export function initAdminCommon() {
     }
   }
 
-  function onOAuth2Change(applyDefaultValues) {
+  function onOAuth2Change(applyDefaultValues: boolean) {
     hideElem('.open_id_connect_auto_discovery_url, .oauth2_use_custom_url');
-    for (const input of document.querySelectorAll('.open_id_connect_auto_discovery_url input[required]')) {
+    for (const input of document.querySelectorAll<HTMLInputElement>('.open_id_connect_auto_discovery_url input[required]')) {
       input.removeAttribute('required');
     }
 
-    const provider = document.querySelector('#oauth2_provider').value;
+    const provider = document.querySelector<HTMLInputElement>('#oauth2_provider').value;
     switch (provider) {
       case 'openidConnect':
-        document.querySelector('.open_id_connect_auto_discovery_url input').setAttribute('required', 'required');
+        document.querySelector<HTMLInputElement>('.open_id_connect_auto_discovery_url input').setAttribute('required', 'required');
         showElem('.open_id_connect_auto_discovery_url');
         break;
       default: {
-        const elProviderCustomUrlSettings = document.querySelector(`#${provider}_customURLSettings`);
+        const elProviderCustomUrlSettings = document.querySelector<HTMLInputElement>(`#${provider}_customURLSettings`);
         if (!elProviderCustomUrlSettings) break; // some providers do not have custom URL settings
         const couldChangeCustomURLs = elProviderCustomUrlSettings.getAttribute('data-available') === 'true';
         const mustProvideCustomURLs = elProviderCustomUrlSettings.getAttribute('data-required') === 'true';
@@ -82,7 +82,7 @@ export function initAdminCommon() {
           showElem('.oauth2_use_custom_url'); // show the checkbox
         }
         if (mustProvideCustomURLs) {
-          document.querySelector('#oauth2_use_custom_url').checked = true; // make the checkbox checked
+          document.querySelector<HTMLInputElement>('#oauth2_use_custom_url').checked = true; // make the checkbox checked
         }
         break;
       }
@@ -91,17 +91,17 @@ export function initAdminCommon() {
   }
 
   function onOAuth2UseCustomURLChange(applyDefaultValues) {
-    const provider = document.querySelector('#oauth2_provider').value;
+    const provider = document.querySelector<HTMLInputElement>('#oauth2_provider').value;
     hideElem('.oauth2_use_custom_url_field');
-    for (const input of document.querySelectorAll('.oauth2_use_custom_url_field input[required]')) {
+    for (const input of document.querySelectorAll<HTMLInputElement>('.oauth2_use_custom_url_field input[required]')) {
       input.removeAttribute('required');
     }
 
     const elProviderCustomUrlSettings = document.querySelector(`#${provider}_customURLSettings`);
-    if (elProviderCustomUrlSettings && document.querySelector('#oauth2_use_custom_url').checked) {
+    if (elProviderCustomUrlSettings && document.querySelector<HTMLInputElement>('#oauth2_use_custom_url').checked) {
       for (const custom of ['token_url', 'auth_url', 'profile_url', 'email_url', 'tenant']) {
         if (applyDefaultValues) {
-          document.querySelector(`#oauth2_${custom}`).value = document.querySelector(`#${provider}_${custom}`).value;
+          document.querySelector<HTMLInputElement>(`#oauth2_${custom}`).value = document.querySelector<HTMLInputElement>(`#${provider}_${custom}`).value;
         }
         const customInput = document.querySelector(`#${provider}_${custom}`);
         if (customInput && customInput.getAttribute('data-available') === 'true') {
@@ -115,25 +115,26 @@ export function initAdminCommon() {
   }
 
   function onEnableLdapGroupsChange() {
-    toggleElem(document.querySelector('#ldap-group-options'), $('.js-ldap-group-toggle')[0].checked);
+    const checked = document.querySelector<HTMLInputElement>('.js-ldap-group-toggle')?.checked;
+    toggleElem(document.querySelector('#ldap-group-options'), checked);
   }
 
   // New authentication
-  if (document.querySelector('.admin.new.authentication')) {
-    document.querySelector('#auth_type')?.addEventListener('change', function () {
+  if (document.querySelector<HTMLDivElement>('.admin.new.authentication')) {
+    document.querySelector<HTMLInputElement>('#auth_type')?.addEventListener('change', function () {
       hideElem('.ldap, .dldap, .smtp, .pam, .oauth2, .has-tls, .search-page-size, .sspi');
 
-      for (const input of document.querySelectorAll('.ldap input[required], .binddnrequired input[required], .dldap input[required], .smtp input[required], .pam input[required], .oauth2 input[required], .has-tls input[required], .sspi input[required]')) {
+      for (const input of document.querySelectorAll<HTMLInputElement>('.ldap input[required], .binddnrequired input[required], .dldap input[required], .smtp input[required], .pam input[required], .oauth2 input[required], .has-tls input[required], .sspi input[required]')) {
         input.removeAttribute('required');
       }
 
-      document.querySelector('.binddnrequired')?.classList.remove('required');
+      document.querySelector<HTMLDivElement>('.binddnrequired')?.classList.remove('required');
 
       const authType = this.value;
       switch (authType) {
         case '2': // LDAP
           showElem('.ldap');
-          for (const input of document.querySelectorAll('.binddnrequired input, .ldap div.required:not(.dldap) input')) {
+          for (const input of document.querySelectorAll<HTMLInputElement>('.binddnrequired input, .ldap div.required:not(.dldap) input')) {
             input.setAttribute('required', 'required');
           }
           document.querySelector('.binddnrequired')?.classList.add('required');
@@ -141,32 +142,32 @@ export function initAdminCommon() {
         case '3': // SMTP
           showElem('.smtp');
           showElem('.has-tls');
-          for (const input of document.querySelectorAll('.smtp div.required input, .has-tls')) {
+          for (const input of document.querySelectorAll<HTMLInputElement>('.smtp div.required input, .has-tls')) {
             input.setAttribute('required', 'required');
           }
           break;
         case '4': // PAM
           showElem('.pam');
-          for (const input of document.querySelectorAll('.pam input')) {
+          for (const input of document.querySelectorAll<HTMLInputElement>('.pam input')) {
             input.setAttribute('required', 'required');
           }
           break;
         case '5': // LDAP
           showElem('.dldap');
-          for (const input of document.querySelectorAll('.dldap div.required:not(.ldap) input')) {
+          for (const input of document.querySelectorAll<HTMLInputElement>('.dldap div.required:not(.ldap) input')) {
             input.setAttribute('required', 'required');
           }
           break;
         case '6': // OAuth2
           showElem('.oauth2');
-          for (const input of document.querySelectorAll('.oauth2 div.required:not(.oauth2_use_custom_url,.oauth2_use_custom_url_field,.open_id_connect_auto_discovery_url) input')) {
+          for (const input of document.querySelectorAll<HTMLInputElement>('.oauth2 div.required:not(.oauth2_use_custom_url,.oauth2_use_custom_url_field,.open_id_connect_auto_discovery_url) input')) {
             input.setAttribute('required', 'required');
           }
           onOAuth2Change(true);
           break;
         case '7': // SSPI
           showElem('.sspi');
-          for (const input of document.querySelectorAll('.sspi div.required input')) {
+          for (const input of document.querySelectorAll<HTMLInputElement>('.sspi div.required input')) {
             input.setAttribute('required', 'required');
           }
           break;
@@ -180,39 +181,39 @@ export function initAdminCommon() {
       }
     });
     $('#auth_type').trigger('change');
-    document.querySelector('#security_protocol')?.addEventListener('change', onSecurityProtocolChange);
-    document.querySelector('#use_paged_search')?.addEventListener('change', onUsePagedSearchChange);
-    document.querySelector('#oauth2_provider')?.addEventListener('change', () => onOAuth2Change(true));
-    document.querySelector('#oauth2_use_custom_url')?.addEventListener('change', () => onOAuth2UseCustomURLChange(true));
+    document.querySelector<HTMLInputElement>('#security_protocol')?.addEventListener('change', onSecurityProtocolChange);
+    document.querySelector<HTMLInputElement>('#use_paged_search')?.addEventListener('change', onUsePagedSearchChange);
+    document.querySelector<HTMLInputElement>('#oauth2_provider')?.addEventListener('change', () => onOAuth2Change(true));
+    document.querySelector<HTMLInputElement>('#oauth2_use_custom_url')?.addEventListener('change', () => onOAuth2UseCustomURLChange(true));
     $('.js-ldap-group-toggle').on('change', onEnableLdapGroupsChange);
   }
   // Edit authentication
-  if (document.querySelector('.admin.edit.authentication')) {
-    const authType = document.querySelector('#auth_type')?.value;
+  if (document.querySelector<HTMLDivElement>('.admin.edit.authentication')) {
+    const authType = document.querySelector<HTMLInputElement>('#auth_type')?.value;
     if (authType === '2' || authType === '5') {
-      document.querySelector('#security_protocol')?.addEventListener('change', onSecurityProtocolChange);
+      document.querySelector<HTMLInputElement>('#security_protocol')?.addEventListener('change', onSecurityProtocolChange);
       $('.js-ldap-group-toggle').on('change', onEnableLdapGroupsChange);
       onEnableLdapGroupsChange();
       if (authType === '2') {
-        document.querySelector('#use_paged_search')?.addEventListener('change', onUsePagedSearchChange);
+        document.querySelector<HTMLInputElement>('#use_paged_search')?.addEventListener('change', onUsePagedSearchChange);
       }
     } else if (authType === '6') {
-      document.querySelector('#oauth2_provider')?.addEventListener('change', () => onOAuth2Change(true));
-      document.querySelector('#oauth2_use_custom_url')?.addEventListener('change', () => onOAuth2UseCustomURLChange(false));
+      document.querySelector<HTMLInputElement>('#oauth2_provider')?.addEventListener('change', () => onOAuth2Change(true));
+      document.querySelector<HTMLInputElement>('#oauth2_use_custom_url')?.addEventListener('change', () => onOAuth2UseCustomURLChange(false));
       onOAuth2Change(false);
     }
   }
 
-  if (document.querySelector('.admin.authentication')) {
+  if (document.querySelector<HTMLDivElement>('.admin.authentication')) {
     $('#auth_name').on('input', function () {
       // appSubUrl is either empty or is a path that starts with `/` and doesn't have a trailing slash.
-      document.querySelector('#oauth2-callback-url').textContent = `${window.location.origin}${appSubUrl}/user/oauth2/${encodeURIComponent(this.value)}/callback`;
+      document.querySelector('#oauth2-callback-url').textContent = `${window.location.origin}${appSubUrl}/user/oauth2/${encodeURIComponent((this as HTMLInputElement).value)}/callback`;
     }).trigger('input');
   }
 
   // Notice
-  if (document.querySelector('.admin.notice')) {
-    const detailModal = document.querySelector('#detail-modal');
+  if (document.querySelector<HTMLDivElement>('.admin.notice')) {
+    const detailModal = document.querySelector<HTMLDivElement>('#detail-modal');
 
     // Attach view detail modals
     $('.view-detail').on('click', function () {
@@ -223,7 +224,7 @@ export function initAdminCommon() {
     });
 
     // Select actions
-    const checkboxes = document.querySelectorAll('.select.table .ui.checkbox input');
+    const checkboxes = document.querySelectorAll<HTMLInputElement>('.select.table .ui.checkbox input');
 
     $('.select.action').on('click', function () {
       switch ($(this).data('action')) {
@@ -244,7 +245,7 @@ export function initAdminCommon() {
           break;
       }
     });
-    document.querySelector('#delete-selection')?.addEventListener('click', async function (e) {
+    document.querySelector<HTMLButtonElement>('#delete-selection')?.addEventListener('click', async function (e) {
       e.preventDefault();
       this.classList.add('is-loading', 'disabled');
       const data = new FormData();
index 0d130703aedaaecc543ed788edf0742a18d89d80..16d7a2426f978d8049e41e403a9f14d3d9d950e6 100644 (file)
@@ -3,17 +3,17 @@ import {POST} from '../../modules/fetch.ts';
 
 const {appSubUrl} = window.config;
 
-export function initAdminConfigs() {
-  const elAdminConfig = document.querySelector('.page-content.admin.config');
+export function initAdminConfigs(): void {
+  const elAdminConfig = document.querySelector<HTMLDivElement>('.page-content.admin.config');
   if (!elAdminConfig) return;
 
-  for (const el of elAdminConfig.querySelectorAll('input[type="checkbox"][data-config-dyn-key]')) {
+  for (const el of elAdminConfig.querySelectorAll<HTMLInputElement>('input[type="checkbox"][data-config-dyn-key]')) {
     el.addEventListener('change', async () => {
       try {
         const resp = await POST(`${appSubUrl}/-/admin/config`, {
-          data: new URLSearchParams({key: el.getAttribute('data-config-dyn-key'), value: el.checked}),
+          data: new URLSearchParams({key: el.getAttribute('data-config-dyn-key'), value: String(el.checked)}),
         });
-        const json = await resp.json();
+        const json: Record<string, any> = await resp.json();
         if (json.errorMessage) throw new Error(json.errorMessage);
       } catch (ex) {
         showTemporaryTooltip(el, ex.toString());
index 46fafa7eff05d19919b02d1fec5dcb145fb8efb8..8e97b67bf930c6343056be575bbd0d43b3a7b5a1 100644 (file)
@@ -1,7 +1,7 @@
 import $ from 'jquery';
 
-export function initAdminEmails() {
-  function linkEmailAction(e) {
+export function initAdminEmails(): void {
+  $('.link-email-action').on('click', (e) => {
     const $this = $(this);
     $('#form-uid').val($this.data('uid'));
     $('#form-email').val($this.data('email'));
@@ -9,6 +9,5 @@ export function initAdminEmails() {
     $('#form-activate').val($this.data('activate'));
     $('#change-email-modal').modal('show');
     e.preventDefault();
-  }
-  $('.link-email-action').on('click', linkEmailAction);
+  });
 }
index 925a50130fc8c8007568ad2e57882da44e1dd34b..9f53378b52a769b851e39c295459999e10b356e5 100644 (file)
@@ -7,16 +7,16 @@ export async function initAdminSelfCheck() {
   const elCheckByFrontend = document.querySelector('#self-check-by-frontend');
   if (!elCheckByFrontend) return;
 
-  const elContent = document.querySelector('.page-content.admin .admin-setting-content');
+  const elContent = document.querySelector<HTMLDivElement>('.page-content.admin .admin-setting-content');
 
   // send frontend self-check request
   const resp = await POST(`${appSubUrl}/-/admin/self_check`, {
     data: new URLSearchParams({
       location_origin: window.location.origin,
-      now: Date.now(), // TODO: check time difference between server and client
+      now: String(Date.now()), // TODO: check time difference between server and client
     }),
   });
-  const json = await resp.json();
+  const json: Record<string, any> = await resp.json();
   toggleElem(elCheckByFrontend, Boolean(json.problems?.length));
   for (const problem of json.problems ?? []) {
     const elProblem = document.createElement('div');
index 7cac603b5c3b68746884c8f7c2faa0fe4fb7b3be..16276773e126f3492b17cf9c2ec3251547ab16d5 100644 (file)
@@ -1,8 +1,8 @@
-export function initAdminUserListSearchForm() {
+export function initAdminUserListSearchForm(): void {
   const searchForm = window.config.pageData.adminUserListSearchForm;
   if (!searchForm) return;
 
-  const form = document.querySelector('#user-list-search-form');
+  const form = document.querySelector<HTMLFormElement>('#user-list-search-form');
   if (!form) return;
 
   for (const button of form.querySelectorAll(`button[name=sort][value="${searchForm.SortType}"]`)) {
@@ -12,23 +12,23 @@ export function initAdminUserListSearchForm() {
   if (searchForm.StatusFilterMap) {
     for (const [k, v] of Object.entries(searchForm.StatusFilterMap)) {
       if (!v) continue;
-      for (const input of form.querySelectorAll(`input[name="status_filter[${k}]"][value="${v}"]`)) {
+      for (const input of form.querySelectorAll<HTMLInputElement>(`input[name="status_filter[${k}]"][value="${v}"]`)) {
         input.checked = true;
       }
     }
   }
 
-  for (const radio of form.querySelectorAll('input[type=radio]')) {
+  for (const radio of form.querySelectorAll<HTMLInputElement>('input[type=radio]')) {
     radio.addEventListener('click', () => {
       form.submit();
     });
   }
 
-  const resetButtons = form.querySelectorAll('.j-reset-status-filter');
+  const resetButtons = form.querySelectorAll<HTMLAnchorElement>('.j-reset-status-filter');
   for (const button of resetButtons) {
     button.addEventListener('click', (e) => {
       e.preventDefault();
-      for (const input of form.querySelectorAll('input[type=radio]')) {
+      for (const input of form.querySelectorAll<HTMLInputElement>('input[type=radio]')) {
         if (input.name.startsWith('status_filter[')) {
           input.checked = false;
         }
index 8f0a88f130270d45e5b4fed3664b638da64988dc..483d72bd5b94fe815682fcab91bb6f919dfe5ce4 100644 (file)
@@ -1,11 +1,11 @@
 import {svg} from '../svg.ts';
 
-const addPrefix = (str) => `user-content-${str}`;
-const removePrefix = (str) => str.replace(/^user-content-/, '');
-const hasPrefix = (str) => str.startsWith('user-content-');
+const addPrefix = (str: string): string => `user-content-${str}`;
+const removePrefix = (str: string): string => str.replace(/^user-content-/, '');
+const hasPrefix = (str: string): boolean => str.startsWith('user-content-');
 
 // scroll to anchor while respecting the `user-content` prefix that exists on the target
-function scrollToAnchor(encodedId) {
+function scrollToAnchor(encodedId: string): void {
   if (!encodedId) return;
   const id = decodeURIComponent(encodedId);
   const prefixedId = addPrefix(id);
@@ -24,7 +24,7 @@ function scrollToAnchor(encodedId) {
   el?.scrollIntoView();
 }
 
-export function initMarkupAnchors() {
+export function initMarkupAnchors(): void {
   const markupEls = document.querySelectorAll('.markup');
   if (!markupEls.length) return;
 
@@ -39,7 +39,7 @@ export function initMarkupAnchors() {
     }
 
     // remove `user-content-` prefix from links so they don't show in url bar when clicked
-    for (const a of markupEl.querySelectorAll('a[href^="#"]')) {
+    for (const a of markupEl.querySelectorAll<HTMLAnchorElement>('a[href^="#"]')) {
       const href = a.getAttribute('href');
       if (!href.startsWith('#user-content-')) continue;
       a.setAttribute('href', `#${removePrefix(href.substring(1))}`);
@@ -47,15 +47,15 @@ export function initMarkupAnchors() {
 
     // add `user-content-` prefix to user-generated `a[name]` link targets
     // TODO: this prefix should be added in backend instead
-    for (const a of markupEl.querySelectorAll('a[name]')) {
+    for (const a of markupEl.querySelectorAll<HTMLAnchorElement>('a[name]')) {
       const name = a.getAttribute('name');
       if (!name) continue;
-      a.setAttribute('name', addPrefix(a.name));
+      a.setAttribute('name', addPrefix(name));
     }
 
-    for (const a of markupEl.querySelectorAll('a[href^="#"]')) {
+    for (const a of markupEl.querySelectorAll<HTMLAnchorElement>('a[href^="#"]')) {
       a.addEventListener('click', (e) => {
-        scrollToAnchor(e.currentTarget.getAttribute('href')?.substring(1));
+        scrollToAnchor((e.currentTarget as HTMLAnchorElement).getAttribute('href')?.substring(1));
       });
     }
   }
index 0fac4a0a39d64b1f86f6fc246801b4ff1fb4800a..f45b7a8e04afbaf2beff5ddcfbcb3e07a7fb383f 100644 (file)
@@ -1,13 +1,13 @@
 import {svg} from '../svg.ts';
 
-export function makeCodeCopyButton() {
+export function makeCodeCopyButton(): HTMLButtonElement {
   const button = document.createElement('button');
   button.classList.add('code-copy', 'ui', 'button');
   button.innerHTML = svg('octicon-copy');
   return button;
 }
 
-export function renderCodeCopy() {
+export function renderCodeCopy(): void {
   const els = document.querySelectorAll('.markup .code-block code');
   if (!els.length) return;
 
index aff4a3242368ea0219a6545108e9694bd2f0b38d..e826c8fd863a9cdecfbba5ca6685ccbcedc1dd9a 100644 (file)
@@ -1,8 +1,8 @@
-export function displayError(el, err) {
+export function displayError(el: Element, err: Error): void {
   el.classList.remove('is-loading');
   const errorNode = document.createElement('pre');
   errorNode.setAttribute('class', 'ui message error markup-block-error');
-  errorNode.textContent = err.str || err.message || String(err);
+  errorNode.textContent = err.message || String(err);
   el.before(errorNode);
   el.setAttribute('data-render-done', 'true');
 }
index e7f7b7f0c49c229b3c01d533df68a3816953e0a1..b9190b15ce61af58ba453a6cd2875a554541e39e 100644 (file)
@@ -5,7 +5,7 @@ import {renderAsciicast} from './asciicast.ts';
 import {initMarkupTasklist} from './tasklist.ts';
 
 // code that runs for all markup content
-export function initMarkupContent() {
+export function initMarkupContent(): void {
   renderMermaid();
   renderMath();
   renderCodeCopy();
@@ -13,6 +13,6 @@ export function initMarkupContent() {
 }
 
 // code that only runs for comments
-export function initCommentContent() {
+export function initCommentContent(): void {
   initMarkupTasklist();
 }
index c690e0c8b112cafb752b64f189c4ae4167408d38..3f7ef38002c67f009a207e65028f6ed865fe7878 100644 (file)
@@ -12,21 +12,20 @@ type ProcessorContext = {
 
 function prepareProcessors(ctx:ProcessorContext): Processors {
   const processors = {
-    H1(el) {
+    H1(el: HTMLHeadingElement) {
       const level = parseInt(el.tagName.slice(1));
       el.textContent = `${'#'.repeat(level)} ${el.textContent.trim()}`;
     },
-    STRONG(el) {
+    STRONG(el: HTMLElement) {
       return `**${el.textContent}**`;
     },
-    EM(el) {
+    EM(el: HTMLElement) {
       return `_${el.textContent}_`;
     },
-    DEL(el) {
+    DEL(el: HTMLElement) {
       return `~~${el.textContent}~~`;
     },
-
-    A(el) {
+    A(el: HTMLAnchorElement) {
       const text = el.textContent || 'link';
       const href = el.getAttribute('href');
       if (/^https?:/.test(text) && text === href) {
@@ -34,7 +33,7 @@ function prepareProcessors(ctx:ProcessorContext): Processors {
       }
       return href ? `[${text}](${href})` : text;
     },
-    IMG(el) {
+    IMG(el: HTMLImageElement) {
       const alt = el.getAttribute('alt') || 'image';
       const src = el.getAttribute('src');
       const widthAttr = el.hasAttribute('width') ? ` width="${htmlEscape(el.getAttribute('width') || '')}"` : '';
@@ -44,32 +43,29 @@ function prepareProcessors(ctx:ProcessorContext): Processors {
       }
       return `![${alt}](${src})`;
     },
-
-    P(el) {
+    P(el: HTMLParagraphElement) {
       el.textContent = `${el.textContent}\n`;
     },
-    BLOCKQUOTE(el) {
+    BLOCKQUOTE(el: HTMLElement) {
       el.textContent = `${el.textContent.replace(/^/mg, '> ')}\n`;
     },
-
-    OL(el) {
+    OL(el: HTMLElement) {
       const preNewLine = ctx.listNestingLevel ? '\n' : '';
       el.textContent = `${preNewLine}${el.textContent}\n`;
     },
-    LI(el) {
+    LI(el: HTMLElement) {
       const parent = el.parentNode;
-      const bullet = parent.tagName === 'OL' ? `1. ` : '* ';
+      const bullet = (parent as HTMLElement).tagName === 'OL' ? `1. ` : '* ';
       const nestingIdentLevel = Math.max(0, ctx.listNestingLevel - 1);
       el.textContent = `${' '.repeat(nestingIdentLevel * 4)}${bullet}${el.textContent}${ctx.elementIsLast ? '' : '\n'}`;
       return el;
     },
-    INPUT(el) {
+    INPUT(el: HTMLInputElement) {
       return el.checked ? '[x] ' : '[ ] ';
     },
-
-    CODE(el) {
+    CODE(el: HTMLElement) {
       const text = el.textContent;
-      if (el.parentNode && el.parentNode.tagName === 'PRE') {
+      if (el.parentNode && (el.parentNode as HTMLElement).tagName === 'PRE') {
         el.textContent = `\`\`\`\n${text}\n\`\`\`\n`;
         return el;
       }
@@ -86,7 +82,7 @@ function prepareProcessors(ctx:ProcessorContext): Processors {
   return processors;
 }
 
-function processElement(ctx :ProcessorContext, processors: Processors, el: HTMLElement) {
+function processElement(ctx :ProcessorContext, processors: Processors, el: HTMLElement): string | void {
   if (el.hasAttribute('data-markdown-generated-content')) return el.textContent;
   if (el.tagName === 'A' && el.children.length === 1 && el.children[0].tagName === 'IMG') {
     return processElement(ctx, processors, el.children[0] as HTMLElement);
index e10d90fa2a9da4f55a2777af498120789955e897..34ca79f493c0301de6373eda8431ab414a17c345 100644 (file)
@@ -1,12 +1,12 @@
 import {displayError} from './common.ts';
 
-function targetElement(el) {
+function targetElement(el: Element) {
   // The target element is either the current element if it has the
   // `is-loading` class or the pre that contains it
   return el.classList.contains('is-loading') ? el : el.closest('pre');
 }
 
-export async function renderMath() {
+export async function renderMath(): void {
   const els = document.querySelectorAll('.markup code.language-math');
   if (!els.length) return;
 
index 5c27d6ca1ceaa77b4d8a3f828431f52352dc4048..004795d3679809b47d004d0e98eaaad91747bb95 100644 (file)
@@ -10,7 +10,7 @@ body {margin: 0; padding: 0; overflow: hidden}
 #mermaid {display: block; margin: 0 auto}
 blockquote, dd, dl, figure, h1, h2, h3, h4, h5, h6, hr, p, pre {margin: 0}`;
 
-export async function renderMermaid() {
+export async function renderMermaid(): Promise<void> {
   const els = document.querySelectorAll('.markup code.language-mermaid');
   if (!els.length) return;
 
index 93896ccf073b761c10e125440600c744ae63fcd9..95db7fc8452ea0e04202e9d3b5eda48f8e6f85d2 100644 (file)
@@ -1,7 +1,7 @@
 import {POST} from '../modules/fetch.ts';
 import {showErrorToast} from '../modules/toast.ts';
 
-const preventListener = (e) => e.preventDefault();
+const preventListener = (e: Event) => e.preventDefault();
 
 /**
  * Attaches `input` handlers to markdown rendered tasklist checkboxes in comments.
@@ -10,10 +10,10 @@ const preventListener = (e) => e.preventDefault();
  * is set accordingly and sent to the server. On success it updates the raw-content on
  * error it resets the checkbox to its original value.
  */
-export function initMarkupTasklist() {
+export function initMarkupTasklist(): void {
   for (const el of document.querySelectorAll(`.markup[data-can-edit=true]`) || []) {
     const container = el.parentNode;
-    const checkboxes = el.querySelectorAll(`.task-list-item input[type=checkbox]`);
+    const checkboxes = el.querySelectorAll<HTMLInputElement>(`.task-list-item input[type=checkbox]`);
 
     for (const checkbox of checkboxes) {
       if (checkbox.hasAttribute('data-editable')) {
@@ -52,7 +52,7 @@ export function initMarkupTasklist() {
         }
 
         try {
-          const editContentZone = container.querySelector('.edit-content-zone');
+          const editContentZone = container.querySelector<HTMLDivElement>('.edit-content-zone');
           const updateUrl = editContentZone.getAttribute('data-update-url');
           const context = editContentZone.getAttribute('data-context');
           const contentVersion = editContentZone.getAttribute('data-content-version');
index 6227a85e33eeaf8ff665b8f37d1099343b926fae..d04f63793f087985a2b6ccf8156a2b3b2c0c44cb 100644 (file)
@@ -153,7 +153,7 @@ export type SvgName = keyof typeof svgs;
 //  most of the SVG icons in assets couldn't be used directly.
 
 // retrieve an HTML string for given SVG icon name, size and additional classes
-export function svg(name: SvgName, size = 16, classNames: string|string[]): string {
+export function svg(name: SvgName, size = 16, classNames?: string|string[]): string {
   const className = Array.isArray(classNames) ? classNames.join(' ') : classNames;
   if (!(name in svgs)) throw new Error(`Unknown SVG icon: ${name}`);
   if (size === 16 && !className) return svgs[name];